diff --git a/org/config/awesome.org b/org/config/awesome.org index 26dd46f..1f00d6f 100644 --- a/org/config/awesome.org +++ b/org/config/awesome.org @@ -33,7 +33,7 @@ and source code of my configuration file which can be extracted to First of all, some initialization is needed, and this initialization is about math randomness. So, let’s initialize the ~random~ method of the ~math~ library: #+BEGIN_SRC lua - math.randomseed(os.time()) +math.randomseed(os.time()) #+END_SRC In order to be able to load libraries properly, I first need to make sure @@ -41,7 +41,7 @@ LuaRocks is installed, so I can also make sure the packages our configuration depends on installed through it can be found. If LuaRocks is not installed, then do nothing. #+BEGIN_SRC lua - pcall(require, "luarocks.loader") +pcall(require, "luarocks.loader") #+END_SRC Next, we’ll also load the following libraries @@ -58,11 +58,11 @@ Next, we’ll also load the following libraries #+NAME: imported-libraries #+BEGIN_SRC emacs-lisp :var libs=table-imported-libraries :cache yes - (mapconcat (lambda (x) (format "local %s = require(\"%s\")" - (cadr x) - (car x))) - libs - "\n") +(mapconcat (lambda (x) (format "local %s = require(\"%s\")" + (cadr x) + (car x))) + libs + "\n") #+END_SRC #+RESULTS[a66d7b66dbd4b4001dc3f649840b66761cc915b5]: imported-libraries @@ -81,17 +81,17 @@ Here is the actual code in the config file: I also want to be able to autofocus the first window when I go to another workspace, so let’s require that: #+BEGIN_SRC lua - require("awful.autofocus") +require("awful.autofocus") #+END_SRC And finally, I want to be able to declare some shortcuts specific to some apps thanks to the hotkeys help widget. #+BEGIN_SRC lua - require("awful.hotkeys_popup.keys") +require("awful.hotkeys_popup.keys") #+END_SRC By the way, let’s initialize the ~random~ method of the ~math~ library: #+BEGIN_SRC lua - math.randomseed(os.time()) +math.randomseed(os.time()) #+END_SRC * Error handling @@ -101,28 +101,28 @@ By the way, let’s initialize the ~random~ method of the ~math~ library: This code checks if Awesome encountered an error during startup and fell back to another config. This code will only ever execute for the fallback config. #+BEGIN_SRC lua - if awesome.startup_errors then - naughty.notify({ preset = naughty.config.presets.critical, - title = "Oops, there were errors during startup!", - text = awesome.startup_errors }) - end +if awesome.startup_errors then + naughty.notify({ preset = naughty.config.presets.critical, + title = "Oops, there were errors during startup!", + text = awesome.startup_errors }) +end #+END_SRC And this code handles runtime errors after startup thanks to signals. #+BEGIN_SRC lua - do - local in_error = false - awesome.connect_signal("debug::error", function (err) - -- Make sure we don't go into an endless error loop - if in_error then return end - in_error = true +do + local in_error = false + awesome.connect_signal("debug::error", function (err) + -- Make sure we don't go into an endless error loop + if in_error then return end + in_error = true - naughty.notify({ preset = naughty.config.presets.critical, - title = "Oops, an error happened!", - text = tostring(err) }) - in_error = false - end) - end + naughty.notify({ preset = naughty.config.presets.critical, + title = "Oops, an error happened!", + text = tostring(err) }) + in_error = false + end) +end #+END_SRC * Variable definitions @@ -138,7 +138,7 @@ Awesome a special look that fits the user. I am currently using a custom theme that is not yet included in my dotfiles. I will add it later, along with the images used for the theme. #+BEGIN_SRC lua - beautiful.init("/home/phundrak/.config/awesome/nord/theme.lua") +beautiful.init("/home/phundrak/.config/awesome/nord/theme.lua") #+END_SRC ** Default terminal and text editor @@ -149,8 +149,8 @@ The two following variables are set so that I don’t need to go over my whole config file in order to modify which terminal or text editor I use, not that I do it often though. #+BEGIN_SRC lua - terminal = "kitty" - editor = os.getenv("EDITOR") or "emacsclient -c -a emacs" +terminal = "kitty" +editor = os.getenv("EDITOR") or "emacsclient -c -a emacs" #+END_SRC ** Keys @@ -163,11 +163,11 @@ Another usual value for this is ~Mod1~, which is the Alt key, but it has greater chances of interfering with other software. I also defined some other obvious variables in order to make my code cleaner later on. #+BEGIN_SRC lua - modkey = "Mod4" - shift = "Shift" - control = "Control" - meta = "Mod1" - alt = "Mod1" -- Just in case +modkey = "Mod4" +shift = "Shift" +control = "Control" +meta = "Mod1" +alt = "Mod1" -- Just in case #+END_SRC * Custom functions @@ -185,12 +185,12 @@ variables in order to make my code cleaner later on. This function sets a random wallpaper from the directory =~/Pictures/Wallpapers=, see [[file:bin.org::#pape-update-bdecbadf][pape-update]] in my custom scripts. #+BEGIN_SRC lua - local function set_random_pape() - awful.spawn.with_shell("pape-update") - naughty.notify({ preset = naughty.config.presets.normal, - title = "Wallpaper change", - text = "Done!"}) - end +local function set_random_pape() + awful.spawn.with_shell("pape-update") + naughty.notify({ preset = naughty.config.presets.normal, + title = "Wallpaper change", + text = "Done!"}) +end #+END_SRC *** Restore previous wallpaper @@ -200,9 +200,9 @@ This function sets a random wallpaper from the directory I also wrote the following function that will restore the previously set wallpaper: #+BEGIN_SRC lua - local function set_wallpaper(_) - awful.spawn.with_shell("nitrogen --restore") - end +local function set_wallpaper(_) + awful.spawn.with_shell("nitrogen --restore") +end #+END_SRC ** Layout manipulation @@ -212,12 +212,12 @@ wallpaper: The following function is used by a shortcut described below in [[#Keybindings-Clients-f9f96d60]]. #+BEGIN_SRC lua - local function client_go_back() - awful.client.focus.history.previous() - if client.focus then - client.focus:raise() - end +local function client_go_back() + awful.client.focus.history.previous() + if client.focus then + client.focus:raise() end +end #+END_SRC ** Clients manipulation @@ -225,43 +225,43 @@ The following function is used by a shortcut described below in :CUSTOM_ID: Custom_functions-Clients_manipulation-7e958fed :END: #+BEGIN_SRC lua - local function restore_minimized_clients() - local c = awful.client.restore() - -- Focus restored client - if c then - c:emit_signal( - "request::activate", "key.unminimize", {raise = true} - ) - end +local function restore_minimized_clients() + local c = awful.client.restore() + -- Focus restored client + if c then + c:emit_signal( + "request::activate", "key.unminimize", {raise = true} + ) end +end #+END_SRC #+BEGIN_SRC lua - local function toggle_fullscreen_client(c) - c.fullscreen = not c.fullscreen - c:raise() - end +local function toggle_fullscreen_client(c) + c.fullscreen = not c.fullscreen + c:raise() +end #+END_SRC #+BEGIN_SRC lua - local function toggle_maximized(c) - c.maximized = not c.maximized - c:raise() - end +local function toggle_maximized(c) + c.maximized = not c.maximized + c:raise() +end #+END_SRC #+BEGIN_SRC lua - local function toggle_vertical_maximized(c) - c.maximized_vertical = not c.maximized_vertical - c:raise() - end +local function toggle_vertical_maximized(c) + c.maximized_vertical = not c.maximized_vertical + c:raise() +end #+END_SRC #+BEGIN_SRC lua - local function toggle_horizontal_maximized(c) - c.maximized_horizontal = not c.maximized_horizontal - c:raise() - end +local function toggle_horizontal_maximized(c) + c.maximized_horizontal = not c.maximized_horizontal + c:raise() +end #+END_SRC ** Tag manipulation @@ -269,45 +269,45 @@ The following function is used by a shortcut described below in :CUSTOM_ID: Custom_functions-Tag_manipulation-5fc67669 :END: #+BEGIN_SRC lua - local function view_tag_n(i) - local screen = awful.screen.focused() - local tag = screen.tags[i] +local function view_tag_n(i) + local screen = awful.screen.focused() + local tag = screen.tags[i] + if tag then + tag:view_only() + end +end +#+END_SRC + +#+BEGIN_SRC lua +local function toggle_tag_n(i) + local screen = awful.screen.focused() + local tag = screen.tags[i] + if tag then + awful.tag.viewtoggle(tag) + end +end +#+END_SRC + +#+BEGIN_SRC lua +local function move_focused_to_tag_n(i) + if client.focus then + local tag = client.focus.screen.tags[i] if tag then - tag:view_only() + client.focus:move_to_tag(tag) end end +end #+END_SRC #+BEGIN_SRC lua - local function toggle_tag_n(i) - local screen = awful.screen.focused() - local tag = screen.tags[i] +local function toggle_focused_client_to_tag_n(i) + if client.focus then + local tag = client.focus.screen.tags[i] if tag then - awful.tag.viewtoggle(tag) - end - end -#+END_SRC - -#+BEGIN_SRC lua - local function move_focused_to_tag_n(i) - if client.focus then - local tag = client.focus.screen.tags[i] - if tag then - client.focus:move_to_tag(tag) - end - end - end -#+END_SRC - -#+BEGIN_SRC lua - local function toggle_focused_client_to_tag_n(i) - if client.focus then - local tag = client.focus.screen.tags[i] - if tag then - client.focus:toggle_tag(tag) - end + client.focus:toggle_tag(tag) end end +end #+END_SRC ** Awesome prompt @@ -315,14 +315,14 @@ The following function is used by a shortcut described below in :CUSTOM_ID: Custom_functions-Awesome_prompt-de4fde50 :END: #+BEGIN_SRC lua - local function invoke_lua_execute_prompt() - awful.prompt.run { - prompt = "Run Lua code: ", - textbox = awful.screen.focused().promptbox.widget, - exe_callback = awful.util.eval, - history_path = awful.util.get_cache_dir() .. "/history_eval" - } - end +local function invoke_lua_execute_prompt() + awful.prompt.run { + prompt = "Run Lua code: ", + textbox = awful.screen.focused().promptbox.widget, + exe_callback = awful.util.eval, + history_path = awful.util.get_cache_dir() .. "/history_eval" + } +end #+END_SRC * Layouts @@ -353,13 +353,13 @@ them, and their order in the table is their order in Awesome. #+NAME: list-layouts #+BEGIN_SRC emacs-lisp :var layouts=table-layouts :cache yes - (mapconcat (lambda (layout) - (let ((enabled-p (string= (cadr layout) "yes")) - (layout (car layout))) - (when enabled-p - (format "awful.layout.suit.%s,\n" layout)))) - layouts - "") +(mapconcat (lambda (layout) + (let ((enabled-p (string= (cadr layout) "yes")) + (layout (car layout))) + (when enabled-p + (format "awful.layout.suit.%s,\n" layout)))) + layouts + "") #+END_SRC #+RESULTS[bf3bbbd40ecc04ec19d9660abff2080b4f68196a]: list-layouts @@ -380,9 +380,9 @@ awful.layout.suit.spiral.dwindle, Here is the code that activates these layouts: #+BEGIN_SRC lua - awful.layout.layouts = { - <> - } +awful.layout.layouts = { + <> +} #+END_SRC * Top bar @@ -399,12 +399,12 @@ below. :END: #+NAME: make-menu #+BEGIN_SRC emacs-lisp :var menu=table-main-menu - (mapconcat (lambda (item) - (format "{ \"%s\", %s }" - (car item) - (mapconcat #'identity (cdr item) ", "))) - menu - ",\n") +(mapconcat (lambda (item) + (format "{ \"%s\", %s }" + (car item) + (mapconcat #'identity (cdr item) ", "))) + menu + ",\n") #+END_SRC #+RESULTS: make-menu @@ -424,9 +424,9 @@ Awesome: And here is the actual code: #+BEGIN_SRC lua - awesomewm_menu = { - <> - } +awesomewm_menu = { + <> +} #+END_SRC Next, let’s create the main menu that will be used on ~S-w~ and at the top left @@ -439,21 +439,21 @@ of the window: Here is the actual code: #+BEGIN_SRC lua - mainmenu = awful.menu({ items = { - <> - }}) +mainmenu = awful.menu({ items = { + <> + }}) #+END_SRC For now it only has two entries: the Awesome menu and opening a terminal, I will add some more later probably. Let’s specify it as being our main launcher: #+BEGIN_SRC lua - launcher = awful.widget.launcher({ image = beautiful.awesome_icon, - menu = mainmenu }) +launcher = awful.widget.launcher({ image = beautiful.awesome_icon, + menu = mainmenu }) #+END_SRC Finally, let’s declare the menubar’s terminal for applications that require it. #+BEGIN_SRC lua - menubar.utils.terminal = terminal +menubar.utils.terminal = terminal #+END_SRC ** Widgets @@ -462,12 +462,12 @@ Finally, let’s declare the menubar’s terminal for applications that require :END: Let’s declare the keyboard map indicator and switcher for the top bar: #+BEGIN_SRC lua - keyboardlayout = awful.widget.keyboardlayout() +keyboardlayout = awful.widget.keyboardlayout() #+END_SRC Let’s also create a clock widget: #+BEGIN_SRC lua - textclock = wibox.widget.textclock() +textclock = wibox.widget.textclock() #+END_SRC ** Tag list @@ -478,9 +478,9 @@ In order to create the taglist (an equivalent to workspaces, but better), we need to create first a local variable that will hold the widget. It will be declared as you can see below: #+BEGIN_SRC lua :tangle no - local tasklist_buttons = gears.table.join( - -- configuration goes here - ) +local tasklist_buttons = gears.table.join( + -- configuration goes here +) #+END_SRC ~gears.table.join()~ joins several tables together, as described [[https://awesomewm.org/doc/api/libraries/gears.table.html][here]], which @@ -493,7 +493,7 @@ tag should switch this tag as the only visible tag, no matter how many of them were visible beforehand. #+NAME: tag-simple-left-click #+BEGIN_SRC lua :tangle no - awful.button({ }, 1, function(t) t:view_only() end) +awful.button({ }, 1, function(t) t:view_only() end) #+END_SRC However, left clicks combined with the modkey will add the clicked tag to the @@ -501,7 +501,7 @@ list of visible tags, which allows the user to see windows from several tags at once. #+NAME: tag-mod-left-click #+BEGIN_SRC lua :tangle no - awful.button({ modkey }, 1, awful.tag.viewtoggle) +awful.button({ modkey }, 1, awful.tag.viewtoggle) #+END_SRC Right clicks are dedicated to window tagging. A simple right click will untag @@ -509,22 +509,22 @@ the currently focused window and tag it again with the clicked tag, moving it effectively from one tag to another. #+NAME: tag-simple-right-click #+BEGIN_SRC lua :tangle no - awful.button({ }, 3, function(t) - if client.focus then - client.focus:move_to_tag(t) - end - end) +awful.button({ }, 3, function(t) + if client.focus then + client.focus:move_to_tag(t) + end +end) #+END_SRC However, a right click combined with the modkey will add the clicked tag to the currently focused window, making it visible to both tags. #+NAME: tag-mod-right-click #+BEGIN_SRC lua :tangle no - awful.button({ modkey }, 3, function(t) - if client.focus then - client.focus:toggle_tag(t) - end - end) +awful.button({ modkey }, 3, function(t) + if client.focus then + client.focus:toggle_tag(t) + end +end) #+END_SRC The scroll wheel is treated as clicks just as any right or left clicks and can @@ -532,25 +532,25 @@ be interpreted by Awesome. They can prove useful when it comes to tags. If a scroll up is detected over tags, then Awesome will display the previous tag. #+NAME: tag-simple-scroll-up #+BEGIN_SRC lua :tangle no - awful.button({ }, 4, function(t) awful.tag.viewprev(t.screen) end) +awful.button({ }, 4, function(t) awful.tag.viewprev(t.screen) end) #+END_SRC Otherwise, if a scroll down is detected, the next tag will be displayed. #+NAME: tag-simple-scroll-down #+BEGIN_SRC lua :tangle no - awful.button({ }, 5, function(t) awful.tag.viewnext(t.screen) end) +awful.button({ }, 5, function(t) awful.tag.viewnext(t.screen) end) #+END_SRC So, here’s the actual configuration code for the taglist: #+BEGIN_SRC lua - local taglist_buttons = gears.table.join( - <>, - <>, - <>, - <>, - <>, - <> - ) +local taglist_buttons = gears.table.join( + <>, + <>, + <>, + <>, + <>, + <> +) #+END_SRC ** Tasks list @@ -560,9 +560,9 @@ So, here’s the actual configuration code for the taglist: Similarly to the tag list, the task list can display some special behavior depending on the clicks it receives. These clicks are set like so: #+BEGIN_SRC lua :tangle no - local tasklist_buttons = gears.table.join( - -- List of clicks - ) +local tasklist_buttons = gears.table.join( + -- List of clicks +) #+END_SRC A left click on a task in the taskbar will simply focus and raise the window @@ -570,17 +570,17 @@ linked to it if it is not focused. Otherwise, if the window is focused, the window will be minimized. #+NAME: task-simple-left-click #+BEGIN_SRC lua :tangle no - awful.button({ }, 1, function (c) - if c == client.focus then - c.minimized = true - else - c:emit_signal( - "request::activate", - "tasklist", - {raise = true} - ) - end - end) +awful.button({ }, 1, function (c) + if c == client.focus then + c.minimized = true + else + c:emit_signal( + "request::activate", + "tasklist", + {raise = true} + ) + end +end) #+END_SRC If the right click is detected, then a list of all the opened clients is invoked @@ -588,36 +588,36 @@ so we can switch to another (and if needed switch visible tag). The width of this list will be 250px. #+NAME: task-simple-right-click #+BEGIN_SRC lua :tangle no - awful.button({ }, 3, function() - awful.menu.client_list({ theme = { width = 250 } }) - end) +awful.button({ }, 3, function() + awful.menu.client_list({ theme = { width = 250 } }) +end) #+END_SRC If a scroll up is detected, then let’s select the previous client in the tasklist. #+NAME: task-simple-scroll-up #+BEGIN_SRC lua :tangle no - awful.button({ }, 4, function () - awful.client.focus.byidx(1) - end) +awful.button({ }, 4, function () + awful.client.focus.byidx(1) +end) #+END_SRC If a scroll down is detected, then let’s select the next client in the tasklist. #+NAME: task-simple-scroll-down #+BEGIN_SRC lua :tangle no - awful.button({ }, 5, function () - awful.client.focus.byidx(-1) - end) +awful.button({ }, 5, function () + awful.client.focus.byidx(-1) +end) #+END_SRC So, here’s the actual code for the tasklist: #+BEGIN_SRC lua - local tasklist_buttons = gears.table.join( - <>, - <>, - <>, - <> - ) +local tasklist_buttons = gears.table.join( + <>, + <>, + <>, + <> +) #+END_SRC * Theme and display @@ -634,16 +634,16 @@ should be redisplayed since it won’t necessarily fit the new geometry of the screen. And remember, I have a [[#Custom_functions-Wallpaper-related_functions-Restore_previous_wallpaper-8b5bc08c][function that does exactly that]]! Let’s connect this function to the geometry change signal: #+BEGIN_SRC lua - screen.connect_signal("property::geometry", set_wallpaper) +screen.connect_signal("property::geometry", set_wallpaper) #+END_SRC If a new screen gets connected, it will need to get a new wallpaper. A lot needs to be done, and all the following lines of code will be inside a block like this: #+BEGIN_SRC lua :tangle no - awful.screen.connect_for_each_screen(function(s) - -- Code to be executed goes here - end) +awful.screen.connect_for_each_screen(function(s) + -- Code to be executed goes here +end) #+END_SRC So, due the code block above, if you see any reference to ~s~ in the code blocks @@ -652,7 +652,7 @@ below, it will refer to the screen being set up by the function. First, let’s set its wallpaper: #+NAME: screen-set-pape #+BEGIN_SRC lua :tangle no - set_wallpaper() +set_wallpaper() #+END_SRC Next, let’s build a list of tags for the screen. *Be aware that each screen has @@ -660,7 +660,7 @@ its own tag table!* The default layout will be the first refered to in the layouts list described above. #+NAME: screen-taglist #+BEGIN_SRC lua :tangle no - awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" }, s, awful.layout.layouts[1]) +awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" }, s, awful.layout.layouts[1]) #+END_SRC Next, let’s create the taglist widget. It will use the ~taglist_buttons~ @@ -668,11 +668,11 @@ Next, let’s create the taglist widget. It will use the ~taglist_buttons~ tags will be displayed in the tagbar ([[https://awesomewm.org/apidoc/widgets/awful.widget.taglist.html#List_filters][more about tag filters]]). #+NAME: screen-taglist-widget #+BEGIN_SRC lua :tangle no - s.taglist = awful.widget.taglist { - screen = s, - filter = awful.widget.taglist.filter.all, - buttons = taglist_buttons - } +s.taglist = awful.widget.taglist { + screen = s, + filter = awful.widget.taglist.filter.all, + buttons = taglist_buttons +} #+END_SRC A tasklist widget will also get created thanks with the ~tasklist_button~ @@ -681,17 +681,17 @@ widget above, the tasklist will only display the screen’s current tags thanks its filter. #+NAME: screen-tasklist-widget #+BEGIN_SRC lua :tangle no - s.tasklist = awful.widget.tasklist { - screen = s, - filter = awful.widget.tasklist.filter.currenttags, - buttons = tasklist_buttons - } +s.tasklist = awful.widget.tasklist { + screen = s, + filter = awful.widget.tasklist.filter.currenttags, + buttons = tasklist_buttons +} #+END_SRC A promptbox will also be created for the screen: #+NAME: screen-promptbox #+BEGIN_SRC lua :tangle no - s.promptbox = awful.widget.prompt() +s.promptbox = awful.widget.prompt() #+END_SRC Then, Let’s create an imagebox widget in which will be contained an icon @@ -701,18 +701,18 @@ next layout will be loaded; otherwise if a right click or a scroll down is detected, the previous layout will be loaded. #+NAME: screen-layout-indicator #+BEGIN_SRC lua :tangle no - s.layoutbox = awful.widget.layoutbox(s) - s.layoutbox:buttons(gears.table.join( - awful.button({ }, 1, function () awful.layout.inc( 1) end), - awful.button({ }, 3, function () awful.layout.inc(-1) end), - awful.button({ }, 4, function () awful.layout.inc( 1) end), - awful.button({ }, 5, function () awful.layout.inc(-1) end))) +s.layoutbox = awful.widget.layoutbox(s) +s.layoutbox:buttons(gears.table.join( + awful.button({ }, 1, function () awful.layout.inc( 1) end), + awful.button({ }, 3, function () awful.layout.inc(-1) end), + awful.button({ }, 4, function () awful.layout.inc( 1) end), + awful.button({ }, 5, function () awful.layout.inc(-1) end))) #+END_SRC Now it is time to create the widget, a ~wibox~ that will contain our bar. #+NAME: screen-wibox-widget #+BEGIN_SRC lua :tangle no - s.wibox = awful.wibar({ position = "top", screen = s }) +s.wibox = awful.wibar({ position = "top", screen = s }) #+END_SRC Finally, let’s set up our bar. Since it is a horizontal bar, its layout will be @@ -721,37 +721,37 @@ widgets, while the tasklist will be at the center, and the keyboard indicator, the system tray, the clock and the layout indicator will be on the right. #+NAME: screen-wibox-setup #+BEGIN_SRC lua :tangle no - s.wibox:setup { - layout = wibox.layout.align.horizontal, - { -- Left widgets - layout = wibox.layout.fixed.horizontal, - launcher, - s.taglist, - s.promptbox, - }, - s.tasklist, -- Middle widget - { -- Right widgets - layout = wibox.layout.fixed.horizontal, - keyboardlayout, - wibox.widget.systray(), - textclock, - s.layoutbox, - }, - } +s.wibox:setup { + layout = wibox.layout.align.horizontal, + { -- Left widgets + layout = wibox.layout.fixed.horizontal, + launcher, + s.taglist, + s.promptbox, + }, + s.tasklist, -- Middle widget + { -- Right widgets + layout = wibox.layout.fixed.horizontal, + keyboardlayout, + wibox.widget.systray(), + textclock, + s.layoutbox, + }, +} #+END_SRC In the end, our code looks like this: #+BEGIN_SRC lua - awful.screen.connect_for_each_screen(function(s) - <> - <> - <> - <> - <> - <> - <> - <> - end) +awful.screen.connect_for_each_screen(function(s) + <> + <> + <> + <> + <> + <> + <> + <> +end) #+END_SRC * Mouse bindings @@ -762,9 +762,9 @@ It is possible with Awesome to bind some shortcuts to mouse events when the mouse is above Awesome itself (not above some client). Only one is set: the right click opens the Awesome menu. #+BEGIN_SRC lua - root.buttons(gears.table.join( - awful.button({}, 3, function() mainmenu:toggle() end) - )) +root.buttons(gears.table.join( + awful.button({}, 3, function() mainmenu:toggle() end) +)) #+END_SRC I will also set three mouse bindings for when the mouse is above a client: @@ -777,24 +777,24 @@ I will also set three mouse bindings for when the mouse is above a client: focusing it and making it a floating client. #+BEGIN_SRC lua - clientbuttons = gears.table.join( - awful.button({ }, 1, function (c) - c:emit_signal("request::activate", "mouse_click", {raise = true}) - end), - awful.button({ modkey }, 1, function (c) - c:emit_signal("request::activate", "mouse_click", {raise = true}) - c.floating = true - awful.mouse.client.move(c) - end), - awful.button({ modkey }, 2, function (c) - awful.client.floating.toggle(c) - end), - awful.button({ modkey }, 3, function (c) - c:emit_signal("request::activate", "mouse_click", {raise = true}) - c.floating = true - awful.mouse.client.resize(c) - end) - ) +clientbuttons = gears.table.join( + awful.button({ }, 1, function (c) + c:emit_signal("request::activate", "mouse_click", {raise = true}) + end), + awful.button({ modkey }, 1, function (c) + c:emit_signal("request::activate", "mouse_click", {raise = true}) + c.floating = true + awful.mouse.client.move(c) + end), + awful.button({ modkey }, 2, function (c) + awful.client.floating.toggle(c) + end), + awful.button({ modkey }, 3, function (c) + c:emit_signal("request::activate", "mouse_click", {raise = true}) + c.floating = true + awful.mouse.client.resize(c) + end) +) #+END_SRC * Keybindings @@ -830,113 +830,113 @@ Here is a description of the tables displayed below: #+NAME: gen-sc-text #+BEGIN_SRC emacs-lisp - (lambda (x) - (let ((key (nth 0 x)) - (modifiers (nth 1 x)) - (lambda-p (pcase (nth 2 x) - ("yes" 'lambda) - ("shell" 'shell) - ("terminal" 'terminal) - ("spawn" 'spawn) - (otherwise nil))) - (action (nth 3 x)) - (description (nth 4 x)) - (group (nth 5 x)) - (clientkey (if (string= (nth 6 x) "yes") "c" ""))) - (format "awful.key({%s},\"%s\",%s,\n\t{description=\"%s\",group=\"%s\"})" - modifiers - key - (if (not lambda-p) - action - (format "function(%s) %s end" clientkey - (pcase lambda-p - ('lambda action) - ('shell - (format "awful.spawn.with_shell(\"%s\")" action)) - ('terminal - (format "awful.spawn(terminal..\" -e %s\")" action)) - ('spawn - (format "awful.spawn(\"%s\")" action))))) - description - group))) +(lambda (x) + (let ((key (nth 0 x)) + (modifiers (nth 1 x)) + (lambda-p (pcase (nth 2 x) + ("yes" 'lambda) + ("shell" 'shell) + ("terminal" 'terminal) + ("spawn" 'spawn) + (otherwise nil))) + (action (nth 3 x)) + (description (nth 4 x)) + (group (nth 5 x)) + (clientkey (if (string= (nth 6 x) "yes") "c" ""))) + (format "awful.key({%s},\"%s\",%s,\n\t{description=\"%s\",group=\"%s\"})" + modifiers + key + (if (not lambda-p) + action + (format "function(%s) %s end" clientkey + (pcase lambda-p + ('lambda action) + ('shell + (format "awful.spawn.with_shell(\"%s\")" action)) + ('terminal + (format "awful.spawn(terminal..\" -e %s\")" action)) + ('spawn + (format "awful.spawn(\"%s\")" action))))) + description + group))) #+END_SRC #+NAME: gen-sc-glob #+BEGIN_SRC emacs-lisp :var table=sc-client - (mapconcat - <> - (seq-filter (lambda (x) - (let ((clientkey-p (nth 6 x))) - (or (not clientkey-p) - (string= "no" clientkey-p)))) - table) - ",\n") +(mapconcat + <> + (seq-filter (lambda (x) + (let ((clientkey-p (nth 6 x))) + (or (not clientkey-p) + (string= "no" clientkey-p)))) + table) + ",\n") #+END_SRC #+NAME: gen-sc-client #+BEGIN_SRC emacs-lisp :var table=sc-client :cache yes - (mapconcat - <> - (seq-filter (lambda (keybind) - (string= "yes" (nth 6 keybind))) - table) - ",\n") +(mapconcat + <> + (seq-filter (lambda (keybind) + (string= "yes" (nth 6 keybind))) + table) + ",\n") #+END_SRC #+NAME: sc-tag-num-gen #+BEGIN_SRC emacs-lisp :var input=sc-tag-num :results drawer :wrap src lua - (let (result) - (dotimes (i 10 result) - (let* ((j (+ 1 i))) - (setq result - (cons - (mapconcat - (lambda (line) - (format - "awful.key({%s},\"#%d\",function() %s%d) end, - \t{description=\"%s%d\",group=\"%s\"})" - (nth 1 line) (+ j 9) (nth 2 line) j - (nth 3 line) j (nth 4 line))) - input - ",\n") result)))) - (mapconcat (lambda (x) x) - result - ",\n\n")) +(let (result) + (dotimes (i 10 result) + (let* ((j (+ 1 i))) + (setq result + (cons + (mapconcat + (lambda (line) + (format + "awful.key({%s},\"#%d\",function() %s%d) end, +\t{description=\"%s%d\",group=\"%s\"})" + (nth 1 line) (+ j 9) (nth 2 line) j + (nth 3 line) j (nth 4 line))) + input + ",\n") result)))) + (mapconcat (lambda (x) x) + result + ",\n\n")) #+END_SRC Most of these keybindings are available at root-level of Awesome and will be declared in the ~globalkeys~ variable, which will be added then to ~root.keys~ (see [[https://awesomewm.org/doc/api/libraries/root.html#keys]]). #+BEGIN_SRC lua :cache yes - globalkeys = gears.table.join( - -- Awesome - <>, - -- App - <>, - <>, - <>, - <>, - <>, - -- Client - <>, - -- Layout - <>, - -- Media - <>, - -- Screen - <>, - -- Tags - <>, - -- Misc - <>, - <> - ) - root.keys(globalkeys) +globalkeys = gears.table.join( + -- Awesome + <>, + -- App + <>, + <>, + <>, + <>, + <>, + -- Client + <>, + -- Layout + <>, + -- Media + <>, + -- Screen + <>, + -- Tags + <>, + -- Misc + <>, + <> +) +root.keys(globalkeys) - clientkeys = gears.table.join( - -- Client - <> - ) +clientkeys = gears.table.join( + -- Client + <> +) #+END_SRC ** Applications @@ -1152,19 +1152,19 @@ when the latter spawn, such as their placement, their properties or even execute a script. A rule can be applied through the ~manage~ signal, and they are all stored in ~awful.rules.rules~, the global rules table, as follows: #+BEGIN_SRC lua :tangle no - awful.rules.rules = { - -- Rules here - } +awful.rules.rules = { + -- Rules here +} #+END_SRC # Block for exporting rules from below #+BEGIN_SRC lua :exports none - awful.rules.rules = { - <>, - <>, - <>, - <> - } +awful.rules.rules = { + <>, + <>, + <>, + <> +} #+END_SRC For more documentation on rules and their syntax, you can read the [[https://awesomewm.org/doc/api/libraries/awful.rules.html][official @@ -1177,11 +1177,11 @@ documentation]]. The first rule is a universal rule which will match all clients, as you can see with its syntax below: #+BEGIN_SRC lua :tangle no - { rule = {}, - properties = { - -- List of properties - } +{ rule = {}, + properties = { + -- List of properties } +} #+END_SRC Here is the list of properties with their value to apply to all clients, and a @@ -1201,12 +1201,12 @@ short explanation as to what they do. #+NAME: rules-universal-properties #+BEGIN_SRC emacs-lisp :tangle no :exports none :var properties=rules-universal-properties-table :cache yes - (mapconcat (lambda (x) - (format "%s = %s" - (car x) - (cadr x))) - properties - ",\n") +(mapconcat (lambda (x) + (format "%s = %s" + (car x) + (cadr x))) + properties + ",\n") #+END_SRC #+RESULTS[5ddcb42f901ac56237de5ed102800b588f462100]: rules-universal-properties @@ -1223,11 +1223,11 @@ short explanation as to what they do. This is what my universal rules look like: #+NAME: rules-universal #+BEGIN_SRC lua :tangle no - { rule = {}, - properties = { - <> - } + { rule = {}, + properties = { + <> } + } #+END_SRC ** Floating clients @@ -1248,10 +1248,10 @@ declare a rule that will match any of the provided conditions: #+NAME: rules-floating-conditions #+BEGIN_SRC emacs-lisp :exports none :tangle no :var conditions=rules-floating-conditions-table :cache yes - (mapconcat (lambda (x) - (format "%s = { \"%s\" }" (car x) (cadr x))) - conditions - ",\n") +(mapconcat (lambda (x) + (format "%s = { \"%s\" }" (car x) (cadr x))) + conditions + ",\n") #+END_SRC #+RESULTS[1fbe7dc1e85b5170957c9583e39c4cbec9a7d7ca]: rules-floating-conditions @@ -1266,9 +1266,9 @@ If any of these conditions is matched, then the client will be set as floating, as you can see below: #+NAME: rules-floating #+BEGIN_SRC lua :tangle no - { rule_any = { - <> - }, properties = { floating = true }} +{ rule_any = { + <> +}, properties = { floating = true }} #+END_SRC ** Titlebars @@ -1278,9 +1278,9 @@ as you can see below: Any normal or dialog client will get a titlebar. This is enabled like so: #+NAME: rules-titlebars #+BEGIN_SRC lua :tangle no - { rule_any = {type = { "normal", "dialog" } - }, properties = { titlebars_enabled = true } - } +{ rule_any = {type = { "normal", "dialog" } + }, properties = { titlebars_enabled = true } +} #+END_SRC ** Default tag for clients @@ -1304,11 +1304,11 @@ to which tag by default. #+NAME: rules-default-tags-generate #+BEGIN_SRC emacs-lisp :tangle no :exports none :cache yes :var tags=rules-default-tags-table - (mapconcat (lambda (x) - (format "{rule = {%s = \"%s\"}, properties = {screen = 1, tag = \"%d\"} }" - (nth 0 x) (nth 1 x) (nth 2 x))) - tags - ",\n") +(mapconcat (lambda (x) + (format "{rule = {%s = \"%s\"}, properties = {screen = 1, tag = \"%d\"} }" + (nth 0 x) (nth 1 x) (nth 2 x))) + tags + ",\n") #+END_SRC #+RESULTS[b1e188e8810460c2f84b6d9cb819430af300d9d0]: rules-default-tags-generate @@ -1325,7 +1325,7 @@ to which tag by default. This is what these rules look like: #+NAME: rules-default-tags #+BEGIN_SRC lua :tangle no - <> +<> #+END_SRC * Signals @@ -1344,14 +1344,14 @@ following snippet ensures this new client is not off the screen, unless its position was deliberately set by a program or by the user. It will also spawn the new client where the mouse currently is. #+BEGIN_SRC lua - client.connect_signal("manage", function (c) - awful.client.movetoscreen(c, mouse.screen) - if awesome.startup - and not c.size_hints.user_position - and not c.size_hints.program_position then - awful.placement.no_offscreen(c) - end - end) +client.connect_signal("manage", function (c) + awful.client.movetoscreen(c, mouse.screen) + if awesome.startup + and not c.size_hints.user_position + and not c.size_hints.program_position then + awful.placement.no_offscreen(c) + end +end) #+END_SRC ** Titlebar creation @@ -1363,13 +1363,13 @@ create titlebar (generally for new clients). The following snippet handles this titlebar creation if titlebar creation was set to ~true~ in the [[#Rules-c6142cdf][rules]]. For a detailed explanation of the code, see below. #+BEGIN_SRC lua - client.connect_signal("request::titlebars", function(c) - local buttons = gears.table.join( - <>, - <> - ) - <> - end) +client.connect_signal("request::titlebars", function(c) + local buttons = gears.table.join( + <>, + <> + ) + <> +end) #+END_SRC The function has two main parts: the creation of the titlebar buttons (mouse @@ -1378,29 +1378,29 @@ of the button is done by creating a local variable ~buttons~ which will be a table created by the library ~gears~, in which will be buttons created by the user. #+BEGIN_SRC lua :tangle no - local buttons = gears.table.join( - -- Buttons declared here - ) +local buttons = gears.table.join( + -- Buttons declared here +) #+END_SRC You can see a left click will enable the user to raise the window, but also it will enable the user to move the window (if it is floating of course). #+NAME: signal-titlebar-button1 #+BEGIN_SRC lua :tangle no - awful.button({ }, 1, function() - c:emit_signal("request::activate", "titlebar", {raise = true}) - awful.mouse.client.move(c) - end) +awful.button({ }, 1, function() + c:emit_signal("request::activate", "titlebar", {raise = true}) + awful.mouse.client.move(c) +end) #+END_SRC A right click on the titlebar will also raise the window, but will instead allow the user to resize the client. #+NAME: signal-titlebar-button3 #+BEGIN_SRC lua :tangle no - awful.button({ }, 3, function() - c:emit_signal("request::activate", "titlebar", {raise = true}) - awful.mouse.client.resize(c) - end) +awful.button({ }, 3, function() + c:emit_signal("request::activate", "titlebar", {raise = true}) + awful.mouse.client.resize(c) +end) #+END_SRC Next comes the actual creation of the titlebar for the client ~c~. For that, we @@ -1408,9 +1408,9 @@ call ~awful.titlebar()~, tell it where the titlebar should be relative to the client and what its setup should be. The full call should look like so: #+NAME: signal-titlebar-create #+BEGIN_SRC lua :tangle no - awful.titlebar(c, {position="left", size = 22}) : setup { - <> - } +awful.titlebar(c, {position="left", size = 22}) : setup { + <> +} #+END_SRC In the setup, I need to repeat to Awesome the titlebar should be on the left of @@ -1433,21 +1433,21 @@ vertically aligned, and then I can declare my bottom elements: aligned #+NAME: signal-titlebar-setup #+BEGIN_SRC lua :tangle no - { -- Top - awful.titlebar.widget.closebutton(c), - awful.titlebar.widget.minimizebutton(c), - awful.titlebar.widget.maximizedbutton(c), - layout = wibox.layout.fixed.vertical() - }, - { - layout = wibox.layout.fixed.vertical() - }, -- Middle - { -- Bottom - awful.titlebar.widget.floatingbutton(c), - layout = wibox.layout.fixed.vertical() - }, - layout = wibox.layout.align.vertical, - position = "left" +{ -- Top + awful.titlebar.widget.closebutton(c), + awful.titlebar.widget.minimizebutton(c), + awful.titlebar.widget.maximizedbutton(c), + layout = wibox.layout.fixed.vertical() +}, +{ + layout = wibox.layout.fixed.vertical() +}, -- Middle +{ -- Bottom + awful.titlebar.widget.floatingbutton(c), + layout = wibox.layout.fixed.vertical() +}, +layout = wibox.layout.align.vertical, +position = "left" #+END_SRC ** Changes of focus @@ -1459,9 +1459,9 @@ makes windows hovered by the user’s mouse focused. Just for completeness’ sa I included it in this document, but be aware this won’t be tangled into my configuration file and focus will not follow my mouse. #+BEGIN_SRC lua :tangle no - client.connect_signal("mouse::enter", function(c) - c:emit_signal("request::activate", "mouse_enter", {raise = false}) - end) +client.connect_signal("mouse::enter", function(c) + c:emit_signal("request::activate", "mouse_enter", {raise = false}) +end) #+END_SRC It is also possible to change the color of the borders based on client focus. @@ -1469,8 +1469,8 @@ While my clients don’t have any border, they do have a titlebar which color changes based on the client’s focus. This is handled by the following code snippet: #+BEGIN_SRC lua - client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end) - client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end) +client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end) +client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end) #+end_SRC * Autostart @@ -1482,7 +1482,7 @@ some autolaunch. All of my autolaunched apps are launch through a custom script which you can [[file:~/org/config/bin.org::#Autostart-a99e99e7][find here]]. The command gets called with ~awful.spawn.with_shell()~, as you can see below. #+BEGIN_SRC lua - awful.spawn.with_shell("autostart") +awful.spawn.with_shell("autostart") #+END_SRC * What to do now :noexport: diff --git a/org/config/bin.org b/org/config/bin.org index 33bb602..b6c131b 100644 --- a/org/config/bin.org +++ b/org/config/bin.org @@ -43,19 +43,19 @@ of said command running. #+NAME: autostart-gen #+BEGIN_SRC emacs-lisp :var table=autostart-table :cache yes - (mapconcat (lambda (start-command) - (let* ((command (s-replace "~" "" (nth 0 start-command))) - (arguments (s-replace "~" "" (nth 1 start-command))) - (once? (string= "yes" (nth 2 start-command)))) - (if once? - (format "pgrep -x %s 2&>/dev/null || echo (%s) 2&>/dev/null" - command - (s-collapse-whitespace (format "%s %s & && disown" - command - arguments))) - (format "%s %s &" command arguments)))) - table - "\n") +(mapconcat (lambda (start-command) + (let* ((command (s-replace "~" "" (nth 0 start-command))) + (arguments (s-replace "~" "" (nth 1 start-command))) + (once? (string= "yes" (nth 2 start-command)))) + (if once? + (format "pgrep -x %s 2&>/dev/null || echo (%s) 2&>/dev/null" + command + (s-collapse-whitespace (format "%s %s & && disown" + command + arguments))) + (format "%s %s &" command arguments)))) + table + "\n") #+END_SRC #+RESULTS[6bdde37274cbbcce2fcd7e86690ce9ce7f32c62f]: autostart-gen @@ -74,15 +74,14 @@ as my default audio output. However, it might not be always connected, hence the following code: #+NAME: default-soundcard #+BEGIN_SRC fish :tangle no - set SOUNDCARD "alsa_output.usb-Focusrite_Scarlett_2i2_USB_Y8KJ6NH094EF1C-00.analog-stereo" - pactl list short sinks | grep $SOUNDCARD 2&> /dev/null && pactl set-default-sink $SOUNDCARD +set SOUNDCARD "alsa_output.usb-Focusrite_Scarlett_2i2_USB_Y8KJ6NH094EF1C-00.analog-stereo" +pactl list short sinks | grep $SOUNDCARD 2&> /dev/null && pactl set-default-sink $SOUNDCARD #+END_SRC #+BEGIN_SRC fish :noweb yes - set -l PATH $PATH /usr/lib/xfce-polkit - - <> - <> +set -l PATH $PATH /usr/lib/xfce-polkit +<> +<> #+END_SRC * Screen utilities @@ -98,8 +97,8 @@ following code: external monitor. First, let’s set some variables so we don’t have to type in hidden places some values that should be easily modifiable. #+BEGIN_SRC fish - set internal "eDP1" - set external "HDMI1" +set internal "eDP1" +set external "HDMI1" #+END_SRC Now, let’s set the ~DETECTEDSCREEN~ variable with a simple ~grep~. If the @@ -111,11 +110,11 @@ once we’ve got that, we can set our external monitor as the main monitor with its maximum resolution. i3 is also restarted in order to properly display the wallpaper and Polybar on the new screen. #+BEGIN_SRC fish - set externaldisplay (xrandr -q --current | grep -A 1 -i "$external connected") - if test -n "$externaldisplay" - set resolution (echo $externaldisplay[2] | awk '{$1=$1;print $1}') - xrandr --output "$external" --primary --auto --mode "$resolution" --right-of "$internal" - end +set externaldisplay (xrandr -q --current | grep -A 1 -i "$external connected") +if test -n "$externaldisplay" + set resolution (echo $externaldisplay[2] | awk '{$1=$1;print $1}') + xrandr --output "$external" --primary --auto --mode "$resolution" --right-of "$internal" +end #+END_SRC * cli utilities @@ -131,7 +130,7 @@ wallpaper and Polybar on the new screen. file and add the date at which it was copied in the filename. You can see its source code here: #+BEGIN_SRC fish - cp -r $argv[1] $argv[1].bak.(date +"%Y%m%d%H%M%S") +cp -r $argv[1] $argv[1].bak.(date +"%Y%m%d%H%M%S") #+END_SRC ** Development @@ -158,9 +157,9 @@ given to =cppnew=. First of all, if no arguments were passed, return an error. #+begin_src fish - if ! count $argv >/dev/null - echo "Missing argument: PROJECT" && return -1 - end +if ! count $argv >/dev/null + echo "Missing argument: PROJECT" && return -1 +end #+end_src Now, let’s set a couple of variables which will prove useful later on when @@ -175,9 +174,9 @@ trying to set up our project. a CMake template C project from the template that already exists in [[file:~/dev/templateC][~/dev/templateC]]. If no argument was passed, display an error message and exit. #+BEGIN_SRC fish - if ! count $argv > /dev/null - echo "Missing argument: PROJECT" && return -1 - end +if ! count $argv > /dev/null + echo "Missing argument: PROJECT" && return -1 +end #+END_SRC Pass the first argument to a switch statement. @@ -188,15 +187,15 @@ switch "$argv[1]" If the argument is =-h= or =--help=, then display the help message and exit the script normally. #+BEGIN_SRC fish - case -h --help - man ~/dev/fishfunctions/cnew.man - exit 0 +case -h --help + man ~/dev/fishfunctions/cnew.man + exit 0 #+END_SRC Else, the argument is the name of the project the user wants to create. #+BEGIN_SRC fish - case '*' - set -g project_name $argv[1] +case '*' + set -g project_name $argv[1] #+END_SRC Let’s close the switch statement. @@ -207,23 +206,23 @@ end Now, let’s copy the template where the user is executing =cnew= from, give it the name of the project and move to the project. #+BEGIN_SRC fish - cp -r ~/dev/templateC $argv[1] - cd $argv[1] +cp -r ~/dev/templateC $argv[1] +cd $argv[1] #+END_SRC The default files have a placeholder for the name of the project. Let’s replace these placeholders with the project’s name. #+BEGIN_SRC fish - sed -i "s/PROJECTNAME/$argv[1]/g" CMakeLists.txt - sed -i "s/PROJECTNAME/$argv[1]/g" README.org - sed -i "s/CPROJECTNAME/$argv[1]/g" doc/Doxyfile +sed -i "s/PROJECTNAME/$argv[1]/g" CMakeLists.txt +sed -i "s/PROJECTNAME/$argv[1]/g" README.org +sed -i "s/CPROJECTNAME/$argv[1]/g" doc/Doxyfile #+END_SRC Now, let’s create a git repository and initialize it. #+BEGIN_SRC fish - git init - git add . - git commit -m "initial commit" +git init +git add . +git commit -m "initial commit" #+END_SRC And we’re done! @@ -237,7 +236,7 @@ Spacemacs' recommendations on how to use Dart with LSP is outdated, since [[https://github.com/natebosch/dart_language_server][=dart_language_server=]] is obsolete. As recommended by the repo owner, we should launch instead the following code: #+BEGIN_SRC fish - /usr/bin/dart $DART_SDK/snapshots/analysis_server.dart.snapshot --lsp +/usr/bin/dart $DART_SDK/snapshots/analysis_server.dart.snapshot --lsp #+END_SRC So, instead of using the obsolete executable, instead we will be calling the @@ -250,10 +249,10 @@ analysis server as requested. :END: This is a simple utility to be ran when the ~flutter~ package is updated. #+BEGIN_SRC fish - sudo chown -R :flutterusers /opt/flutter - sudo chmod -R g+w /opt/flutter - sudo chmod a+rw /opt/flutter/version - sudo chown $USER:(id -g $USER) /opt/flutter/bin/cache +sudo chown -R :flutterusers /opt/flutter +sudo chmod -R g+w /opt/flutter +sudo chmod a+rw /opt/flutter/version +sudo chown $USER:(id -g $USER) /opt/flutter/bin/cache #+END_SRC ** Pinfo :noexport: @@ -273,7 +272,7 @@ useful about SSH is its ability to bind locally the port of a remote machine, and vice versa. The syntax is actually very simple, but I prefer a more intuitive way of writing it. Its usage is ~sshbind PORT FROMHOST TOHOST~. #+BEGIN_SRC fish - ssh -L $argv[1]:$argv[3]:$argv[1] $argv[2] -N +ssh -L $argv[1]:$argv[3]:$argv[1] $argv[2] -N #+END_SRC ** Starwars @@ -284,7 +283,7 @@ intuitive way of writing it. Its usage is ~sshbind PORT FROMHOST TOHOST~. This is a one-liner that allows you to watch Star Wars episode 4 in ASCII art in your terminal. Here is the code: #+BEGIN_SRC fish - telnet towel.blinkenlights.nl +telnet towel.blinkenlights.nl #+END_SRC ** Toggle touchpad tapping @@ -303,29 +302,29 @@ First let’s declare some variables to make this script more personal. With my current computer (a Gazelle by System76), the name of my touchpad is the following: #+BEGIN_SRC fish - set TPNAME "ELAN0412:00 04F3:3162 Touchpad" +set TPNAME "ELAN0412:00 04F3:3162 Touchpad" #+END_SRC Let’s now get the identifier of the touchpad for ~xinput~: #+BEGIN_SRC fish - set TPID (xinput list | grep $TPNAME | awk '{print $6}' | sed 's|id=\(.*\)|\1|g') +set TPID (xinput list | grep $TPNAME | awk '{print $6}' | sed 's|id=\(.*\)|\1|g') #+END_SRC Now, let’s detect the current status of the touchpad: #+BEGIN_SRC fish - set TPSTATUS (xinput list-props $TPID | grep "Tapping Enabled" | \ - grep -v "Default" | awk '{print $5}') +set TPSTATUS (xinput list-props $TPID | grep "Tapping Enabled" | \ + grep -v "Default" | awk '{print $5}') #+END_SRC This will set ~TPSTATUS~ either to ~0~, meaning tapping is disabled, or to ~1~, meaning it’s enabled. I will consider any other value as being disabled. #+BEGIN_SRC fish - test [[ $TPSTATUS = "1" ]] && set NEWTPSTATUS 0 || set NEWTPSTATUS 1 +test [[ $TPSTATUS = "1" ]] && set NEWTPSTATUS 0 || set NEWTPSTATUS 1 #+END_SRC Finally, let’s update the touchpad’s options: #+BEGIN_SRC fish - xinput set-prop $TPNAME "libinput Tapping Enabled" $NEWTPSTATUS +xinput set-prop $TPNAME "libinput Tapping Enabled" $NEWTPSTATUS #+END_SRC ** Wacom setup @@ -343,20 +342,20 @@ to one screen. We need some variables in order to correctly set our tablet. First, let’s get declare what the name of our tablet is, and what the name of its touchpad is. #+BEGIN_SRC fish - set -g DEVICE "Wacom USB Bamboo PAD Pen stylus" +set -g DEVICE "Wacom USB Bamboo PAD Pen stylus" #+END_SRC To get the correct values for the area it can cover, we’ll need to reset our tablet. #+BEGIN_SRC fish - xsetwacom set "$DEVICE" ResetArea +xsetwacom set "$DEVICE" ResetArea #+END_SRC Now we can get the X and Y areas. #+BEGIN_SRC fish - set -g AREATOT (xsetwacom get "$DEVICE" Area) - set -g AREAX (echo $AREATOT | awk '{print $3}') - set -g AREAY (echo $AREATOT | awk '{print $4}') +set -g AREATOT (xsetwacom get "$DEVICE" Area) +set -g AREAX (echo $AREATOT | awk '{print $3}') +set -g AREAY (echo $AREATOT | awk '{print $4}') #+END_SRC *** Select our screen @@ -367,41 +366,41 @@ This function will allow us to select the screen on which the tablet will be active. We can also select the option “desktop” so that all screens are selected. Let’s declare our function. #+BEGIN_SRC fish :noweb yes - function set_screen - <> - <> - <> - <> - end +function set_screen + <> + <> + <> + <> +end #+END_SRC First, let’s set what screens are available, including the desktop option. #+NAME: wacom-screen-get-displays #+BEGIN_SRC fish :tangle no - set CONNECTED_DISPLAYS (xrandr -q --current | \ - sed -n 's/^\([^ ]\+\) connected .*/\1/p') desktop +set CONNECTED_DISPLAYS (xrandr -q --current | \ +sed -n 's/^\([^ ]\+\) connected .*/\1/p') desktop #+END_SRC Now, let’s select the one we wish to use using rofi. #+NAME: wacom-screens-select-screen #+BEGIN_SRC fish :tangle no - set -g SCREEN (for d in $CONNECTED_DISPLAYS - echo $d - end | rofi -dmenu -i -p "Select your dispaly" | tr -d '\n') +set -g SCREEN (for d in $CONNECTED_DISPLAYS + echo $d +end | rofi -dmenu -i -p "Select your dispaly" | tr -d '\n') #+END_SRC We can now get the position of our screen. #+NAME: wacom-screen-get-position #+BEGIN_SRC fish :tangle no - set -g POSITION (xrandr -q --current | sed -nr "s/^$SCREEN connected (primary )*([0-9x\+]+).*/\2/p") +set -g POSITION (xrandr -q --current | sed -nr "s/^$SCREEN connected (primary )*([0-9x\+]+).*/\2/p") #+END_SRC We’ll also get the width and height of the screen so we can set correctly the drawing area of the tablet. #+NAME: wacom-screen-get-dimensions #+BEGIN_SRC fish :tangle no - set -g HEIGHT (echo $POSITION | sed -nr 's/[0-9]+x([0-9]+).*/\1/p') - set -g WIDTH (echo $POSITION | sed -nr 's/([0-9]+)x.*/\1/p') +set -g HEIGHT (echo $POSITION | sed -nr 's/[0-9]+x([0-9]+).*/\1/p') +set -g WIDTH (echo $POSITION | sed -nr 's/([0-9]+)x.*/\1/p') #+END_SRC *** Adjust the tablet @@ -411,11 +410,11 @@ drawing area of the tablet. This function will take care of adjusting our tablet to our screen. Let’s declare our function. #+BEGIN_SRC fish :noweb yes - function adjust_device - <> - <> - <> - end +function adjust_device + <> + <> + <> +end #+END_SRC If our screen is too high or too wide for our tablet, we will have to adjust the @@ -423,8 +422,8 @@ height or width of the area used by the tablet. So let’s get the theoretical n height and width of the area. #+NAME: wacom-tablet-set-ration-area #+BEGIN_SRC fish :tangle no - set RATIOAREAY (math ceil \($AREAX \* $HEIGHT \/ $WIDTH\)) - set RATIOAREAX (math ceil \($AREAY \* $WIDTH \/ $HEIGHT\)) +set RATIOAREAY (math ceil \($AREAX \* $HEIGHT \/ $WIDTH\)) +set RATIOAREAX (math ceil \($AREAY \* $WIDTH \/ $HEIGHT\)) #+END_SRC Now, if the current height of the tablet’s area is greater than the theoretical @@ -433,19 +432,19 @@ other way around. Let’s set =NEWAREAX= and =NEWAREAY= that will be used to set the new area for the tablet. #+NAME: wacom-tablet-set-new-area #+BEGIN_SRC fish :tangle no - if test $AREAY -gt $RATIOAREAY - set -g NEWAREAX $AREAX - set -g NEWAREAY $RATIOAREAY - else - set -g NEWAREAX $RATIOAREAX - set -g NEWAREAY $AREAY - end +if test $AREAY -gt $RATIOAREAY + set -g NEWAREAX $AREAX + set -g NEWAREAY $RATIOAREAY +else + set -g NEWAREAX $RATIOAREAX + set -g NEWAREAY $AREAY +end #+END_SRC Alright, now let’s set the new area with these new variables. #+NAME: wacom-tablet-set-device-area-and-screen #+BEGIN_SRC fish :tangle no - xsetwacom set "$DEVICE" Area 0 0 $NEWAREAX $NEWAREAY +xsetwacom set "$DEVICE" Area 0 0 $NEWAREAX $NEWAREAY #+END_SRC *** Lauch the functions @@ -455,8 +454,8 @@ Alright, now let’s set the new area with these new variables. Back to the main body of the script, we can now launch the functions sequencially. #+BEGIN_SRC fish - set_screen - adjust_device +set_screen +adjust_device #+END_SRC * Emacs stuff @@ -469,7 +468,7 @@ sequencially. :HEADER-ARGS: :shebang "#!/bin/bash" :mkdirp yes :tangle ~/.local/bin/dired :END: #+BEGIN_SRC bash - emacsclient -c -a emacs -e "(dired \"$@\")" +emacsclient -c -a emacs -e "(dired \"$@\")" #+END_SRC ** Emacsmail @@ -480,7 +479,7 @@ sequencially. This short script is used in my =~/.local/share/applications/mu4e.desktop= file in order to send to Emacs any ~mailto:~ requests made in my system. #+BEGIN_SRC bash - emacsclient -c -n -a emacs -e "(browse-url-mail \"$@\")" +emacsclient -c -n -a emacs -e "(browse-url-mail \"$@\")" #+END_SRC * Media @@ -495,7 +494,7 @@ in order to send to Emacs any ~mailto:~ requests made in my system. This function allows me to convert easily an mp4 video to the webm format. Nothing too fancy here. #+BEGIN_SRC fish - ffmpeg -i $argv[1] -c:v libvpx -crf 10 -b:v 1M -c:a libvorbis $argv[1].webm +ffmpeg -i $argv[1] -c:v libvpx -crf 10 -b:v 1M -c:a libvorbis $argv[1].webm #+END_SRC ** youtube-dl wrappers @@ -511,31 +510,31 @@ Nothing too fancy here. YouTube video at the desired resolution. The script relies on ~dmenu~ (or ~rofi~ in dmenu-mode), ~youtube-dl~ and of course ~mpv~ itself. #+BEGIN_SRC fish - set URL (rofi -dmenu -i -p "Video URL") - if test -n "$URL" - set FORMAT \ - (youtube-dl --list-formats "$URL" | \ - egrep "webm.*[0-9]+x[0-9]+" | \ - awk '{print $3 " " $1}' | \ - sort -gu | \ - rofi -dmenu -i -p "Resolution" | \ - string split " ") - set FCODE $FORMAT[2] - mpv --ytdl-format=$FCODE+bestaudio/best "$URL" - end +set URL (rofi -dmenu -i -p "Video URL") +if test -n "$URL" + set FORMAT \ + (youtube-dl --list-formats "$URL" | \ + egrep "webm.*[0-9]+x[0-9]+" | \ + awk '{print $3 " " $1}' | \ + sort -gu | \ + rofi -dmenu -i -p "Resolution" | \ + string split " ") + set FCODE $FORMAT[2] + mpv --ytdl-format=$FCODE+bestaudio/best "$URL" +end #+END_SRC I’ll even add a ~.desktop~ entry for this script: #+BEGIN_SRC conf-desktop :tangle ~/.local/share/applications/ytplay.desktop :mkdirp yes - [Desktop Entry] - Type=Application - Version=1.0 - Name=ytplay (YouTube in mpv) - Comment=Play YouTube videos in mpv - Exec=/home/phundrak/.local/bin/ytplay - Path=/home/phundrak/.local/bin - Terminal=false - Categories=Media +[Desktop Entry] +Type=Application +Version=1.0 +Name=ytplay (YouTube in mpv) +Comment=Play YouTube videos in mpv +Exec=/home/phundrak/.local/bin/ytplay +Path=/home/phundrak/.local/bin +Terminal=false +Categories=Media #+END_SRC *** ytdl - a ~youtube-dl~ wrapper @@ -577,23 +576,23 @@ There is one more default variable pointing to ytdl’s root directory which depends on whether the videos directory has a French or English name: #+NAME: ytdl-default-vars-root #+BEGIN_SRC fish :tangle no - if test -d "$HOME/Vidéos" - set -g ROOTDIR_DEFAULT "$HOME/Vidéos" # French name - else - set -g ROOTDIR_DEFAULT "$HOME/Videos" # English name - end +if test -d "$HOME/Vidéos" + set -g ROOTDIR_DEFAULT "$HOME/Vidéos" # French name +else + set -g ROOTDIR_DEFAULT "$HOME/Videos" # English name +end #+END_SRC #+NAME: ytdl-default-vars-make #+BEGIN_SRC emacs-lisp :var vars=ytdl-default-vars - (mapconcat (lambda (var) - (let ((varname (car var)) - (varvalue (cadr var)) - (string? (string= (nth 2 var) "yes"))) - (format "set -g %-16s %s" varname (if string? (format "\"%s\"" varvalue) - varvalue)))) - vars - "\n") +(mapconcat (lambda (var) + (let ((varname (car var)) + (varvalue (cadr var)) + (string? (string= (nth 2 var) "yes"))) + (format "set -g %-16s %s" varname (if string? (format "\"%s\"" varvalue) + varvalue)))) + vars + "\n") #+END_SRC #+RESULTS: ytdl-default-vars-make @@ -606,14 +605,14 @@ depends on whether the videos directory has a French or English name: : set -g VERSION "0.3" #+BEGIN_SRC fish :noweb yes - <> - <> +<> +<> #+END_SRC We’ll also create the directory pointed at by ~YTDL_SHARED_DIR~ if it doesn’t exist already: #+BEGIN_SRC fish - mkdir -p $YTDL_SHARED_DIR +mkdir -p $YTDL_SHARED_DIR #+END_SRC **** Help message @@ -623,65 +622,65 @@ exist already: The next step is displaying the help message for the script. For that, just a long string echo’d will do, wrapped in the function ~_ytdl_help~. #+BEGIN_SRC fish - function _ytdl_help - echo "Usage: ytdl [OPTION]... URL [URL]... +function _ytdl_help + echo "Usage: ytdl [OPTION]... URL [URL]... - -4, --ipv4 - Download with forced IPv4 - Default: no + -4, --ipv4 + Download with forced IPv4 + Default: no - -6, --ipv6 - Download with forced IPv6 - Default: no + -6, --ipv6 + Download with forced IPv6 + Default: no - -a, --batch-file - File containing URLs to download, one URL per line. Lines starting with - '#', ';' or ']' are considered as comments and ignored. - Default: None + -a, --batch-file + File containing URLs to download, one URL per line. Lines starting with + '#', ';' or ']' are considered as comments and ignored. + Default: None - -c, --id-cache - File containing the video IDs that were already downloaded, one ID per - line. - Default: $DOWNFILE_DEFAULT + -c, --id-cache + File containing the video IDs that were already downloaded, one ID per + line. + Default: $DOWNFILE_DEFAULT - -d, --directory - Root directory in which to download videos. - Default: $ROOTDIR_DEFAULT + -d, --directory + Root directory in which to download videos. + Default: $ROOTDIR_DEFAULT - -e, --error-file - File containing the IDs of videos that failed to download, one ID per - line - Default: $ERRFILE_DEFAULT + -e, --error-file + File containing the IDs of videos that failed to download, one ID per + line + Default: $ERRFILE_DEFAULT - -f, --format - Format name for downloaded videos, including path relative to root - directory - Default: $FORMAT_DEFAULT + -f, --format + Format name for downloaded videos, including path relative to root + directory + Default: $FORMAT_DEFAULT - -l, --logs - File in which to store logs. - Default: $LOGFILE_DEFAULT + -l, --logs + File in which to store logs. + Default: $LOGFILE_DEFAULT - -V, --verbose - Show verbose output - Default: no + -V, --verbose + Show verbose output + Default: no - -v, --version - Show version of ytdl. + -v, --version + Show version of ytdl. - -h, --help - Shows this help message" - end + -h, --help + Shows this help message" +end #+END_SRC We also have the function ~_ytdl_version~ to display the current version of ~ytdl~: #+BEGIN_SRC fish - function _ytdl_version - echo "ytdl 0.3, developped for fish 3.1.0 and youtube-dl 2020.03.24 or newer" - echo "requires Fish getopts " - echo "and ripgrep " - end +function _ytdl_version + echo "ytdl 0.3, developped for fish 3.1.0 and youtube-dl 2020.03.24 or newer" + echo "requires Fish getopts " + echo "and ripgrep " +end #+END_SRC **** Arguments Handling @@ -712,20 +711,20 @@ associated to them, they will be downloaded as part of a single queue. #+NAME: ytdl-arg-handling-gen #+BEGIN_SRC emacs-lisp :var args=ytdl-table-arguments - (mapconcat (lambda (arg) - (let* ((short (format "%s" (nth 0 arg))) - (long (nth 1 arg)) - (arg? (string= "yes" (nth 2 arg))) - (var (unless (string= "None" (nth 3 arg)) - (nth 3 arg)))) - (format "case %s %s\n\t%s" - short long - (if var (format "set -g %s %s" var - (if arg? "$value" "")) - (format "_ytdl_%s && exit" - (if (string= "h" short) "help" "version")))))) - args - "\n") +(mapconcat (lambda (arg) + (let* ((short (format "%s" (nth 0 arg))) + (long (nth 1 arg)) + (arg? (string= "yes" (nth 2 arg))) + (var (unless (string= "None" (nth 3 arg)) + (nth 3 arg)))) + (format "case %s %s\n\t%s" + short long + (if var (format "set -g %s %s" var + (if arg? "$value" "")) + (format "_ytdl_%s && exit" + (if (string= "h" short) "help" "version")))))) + args + "\n") #+END_SRC #+RESULTS: ytdl-arg-handling-gen @@ -758,32 +757,32 @@ The following shows how ~getopts~ is used to catch the options and switches passed to the script: #+NAME: ytdl-getopts #+BEGIN_SRC fish :noweb yes :tangle no - getopts $argv | while read -l key value - switch $key - <> - case _ - for v in $value - set -g VIDEOS $VIDEOS $v - end - end - end +getopts $argv | while read -l key value + switch $key + <> + case _ + for v in $value + set -g VIDEOS $VIDEOS $v + end + end +end #+END_SRC #+NAME: ytdl-arg-set-default-value-gen #+BEGIN_SRC emacs-lisp :var args=ytdl-table-arguments - (let* ((args (-filter (lambda (arg) - (let* ((var (unless (string= "None" (nth 3 arg)) (nth 3 arg))) - (default (format "%s" (nth 4 arg))) - (default (unless (string= "None" default) default))) - (and var default))) - args))) - (mapconcat (lambda (arg) - (let* ((var (nth 3 arg)) - (default (format "%s" (nth 4 arg)))) - (format "if set -q $%s\n\tset -g %s %s\nend" - var var default))) - args - "\n")) +(let* ((args (-filter (lambda (arg) + (let* ((var (unless (string= "None" (nth 3 arg)) (nth 3 arg))) + (default (format "%s" (nth 4 arg))) + (default (unless (string= "None" default) default))) + (and var default))) + args))) + (mapconcat (lambda (arg) + (let* ((var (nth 3 arg)) + (default (format "%s" (nth 4 arg)))) + (format "if set -q $%s\n\tset -g %s %s\nend" + var var default))) + args + "\n")) #+END_SRC #+RESULTS: ytdl-arg-set-default-value-gen @@ -812,16 +811,16 @@ Some values need to be set to their default, so let’s assign them their value no user value was passed: #+NAME: ytdl-arg-set-default-value #+BEGIN_SRC fish :noweb yes :tangle no - <> - set -g FORMAT "$ROOTDIR/$FORMAT" +<> +set -g FORMAT "$ROOTDIR/$FORMAT" #+END_SRC Both these code blocks are executed in ~_ytdl_parse_ops~: #+BEGIN_SRC fish :noweb yes - function _ytdl_parse_ops - <> - <> - end +function _ytdl_parse_ops + <> + <> +end #+END_SRC **** Logging @@ -833,15 +832,15 @@ in the file pointed to by ~LOGFILE~. The first argument the function should receive is its log level. I generally use either ~"INFO"~ or ~"ERR"~. The second argument is the message to log. #+BEGIN_SRC fish - function _ytdl_log - set -l INFOLEVEL $argv[1] - set -l MSG $argv[2] - set -l LOG (printf "[%s] %s %s\n" $INFOLEVEL (date +"%F %T") $MSG) - printf "%s\n" $LOG >> $LOGFILE - if test $VERBOSE -eq 1 - echo $LOG - end - end +function _ytdl_log + set -l INFOLEVEL $argv[1] + set -l MSG $argv[2] + set -l LOG (printf "[%s] %s %s\n" $INFOLEVEL (date +"%F %T") $MSG) + printf "%s\n" $LOG >> $LOGFILE + if test $VERBOSE -eq 1 + echo $LOG + end +end #+END_SRC **** Download a Single Video @@ -863,18 +862,18 @@ the queue length –can be the amount of videos in a whole YouTube channel, the amount of videos in a playlist, or simply the amount of YouTube URLs passed as arguments to the script. #+BEGIN_SRC fish - function _ytdl_download_video - set ID $argv[1] - _ytdl_log "INFO" (printf "Downloading video with ID $ID (%4d/%4d)" $argv[2] $argv[3]) - if youtube-dl -f $PREFFERED_FORMAT -ciw -o $FORMAT "https://youtube.com/watch?v=$ID" - echo $ID >> $DOWNFILE - else if youtube-dl -ciw -o $FORMAT "https://youtube.com/watch?v=$ID" - echo $ID >> $DOWNFILE - else - _ytdl_log "ERR" "Could not download $VIDEO" - echo $ID >> $ERRFILE - end - end +function _ytdl_download_video + set ID $argv[1] + _ytdl_log "INFO" (printf "Downloading video with ID $ID (%4d/%4d)" $argv[2] $argv[3]) + if youtube-dl -f $PREFFERED_FORMAT -ciw -o $FORMAT "https://youtube.com/watch?v=$ID" + echo $ID >> $DOWNFILE + else if youtube-dl -ciw -o $FORMAT "https://youtube.com/watch?v=$ID" + echo $ID >> $DOWNFILE + else + _ytdl_log "ERR" "Could not download $VIDEO" + echo $ID >> $ERRFILE + end +end #+END_SRC /Note that this function is not meant to be called without any checks before./ @@ -890,14 +889,14 @@ ID of the video we want to download is already present in the list of downloaded videos. If not, it will then be downloaded though ~_ytdl_download_video~ described above. #+BEGIN_SRC fish - function _ytdl_download_queue - for i in (seq (count $argv)) - rg -- $argv[$i] $DOWNFILE 2&> /dev/null - if test $status -ne 0 - _ytdl_download_video $argv[$i] $i (count $argv) - end - end - end +function _ytdl_download_queue + for i in (seq (count $argv)) + rg -- $argv[$i] $DOWNFILE 2&> /dev/null + if test $status -ne 0 + _ytdl_download_video $argv[$i] $i (count $argv) + end + end +end #+END_SRC **** Download Videos From Arguments @@ -907,14 +906,14 @@ described above. The main aim of this function is to transform the URLs contained in the arguments passed to the script to a list of IDs usable later on by ~ytdl~. #+BEGIN_SRC fish - function _ytdl_download_arg_urls - set -g IDs - for VIDEO in $argv - _ytdl_log "Info" "Getting video ID for $VIDEO" - set -g IDs $IDs (youtube-dl --get-id $VIDEO) - end - _ytdl_download_queue $IDs - end +function _ytdl_download_arg_urls + set -g IDs + for VIDEO in $argv + _ytdl_log "Info" "Getting video ID for $VIDEO" + set -g IDs $IDs (youtube-dl --get-id $VIDEO) + end + _ytdl_download_queue $IDs +end #+END_SRC **** Download Videos From a Batch File @@ -938,33 +937,33 @@ will even download videos from playlists they decided to put on their channel’ front page, even if it is not theirs. So in that case, we need to append ~/videos~ to any channel URL. #+BEGIN_SRC fish - function _ytdl_download_batch - set -q $FILE - if test $status -eq 1 - set -g NEW - set CHANNELS (cat $FILE | grep -vE "#|;|\]") - for c in $CHANNELS - _ytdl_log "INFO" "Getting IDs for channel $c" - if test (egrep '\/c\/|user|channel' (echo $c |psub)) - set -g IDS (youtube-dl --get-id "$c/videos") - else - set -g IDS (youtube-dl --get-id $c) - end - _ytdl_log "INFO" "Fetching new videos from channel" - for i in (seq (count $IDS)) - printf "\rsearching (%d/%d)" $IDn (count $IDS) - rg -- $IDS[$i] $DOWNFILE 2&> /dev/null - if test $status -ne 0 - set -g NEW $IDS[$i] $NEW - end - end - printf "\n" - end - for i in (seq (count $NEW)) - _ytdl_download_video $NEW[$i] $i (count $NEW) - end - end - end +function _ytdl_download_batch + set -q $FILE + if test $status -eq 1 + set -g NEW + set CHANNELS (cat $FILE | grep -vE "#|;|\]") + for c in $CHANNELS + _ytdl_log "INFO" "Getting IDs for channel $c" + if test (egrep '\/c\/|user|channel' (echo $c |psub)) + set -g IDS (youtube-dl --get-id "$c/videos") + else + set -g IDS (youtube-dl --get-id $c) + end + _ytdl_log "INFO" "Fetching new videos from channel" + for i in (seq (count $IDS)) + printf "\rsearching (%d/%d)" $IDn (count $IDS) + rg -- $IDS[$i] $DOWNFILE 2&> /dev/null + if test $status -ne 0 + set -g NEW $IDS[$i] $NEW + end + end + printf "\n" + end + for i in (seq (count $NEW)) + _ytdl_download_video $NEW[$i] $i (count $NEW) + end + end +end #+END_SRC **** Main Body @@ -975,9 +974,9 @@ Now that we have all our functions declared, let’s call them! First, we need t parse our arguments. We’ll then download all files passed as arguments. Finally, we’ll download videos, playlists and channels specified from a batch file. #+BEGIN_SRC fish - _ytdl_parse_ops $argv - _ytdl_download_arg_urls $VIDEOS - _ytdl_download_batch +_ytdl_parse_ops $argv +_ytdl_download_arg_urls $VIDEOS +_ytdl_download_batch #+END_SRC And that’s all! If you’re interested with a very simple interface for @@ -992,11 +991,11 @@ downloading one video once, I wrote a small [[#rofi-ytdl-ff8f789d][~rofi-ytdl~]] the background image of the locked screen a corrupted screenshot of the screen before it was locked. #+BEGIN_SRC fish - set TMPBG /tmp/screen.png - scrot $TMPBG - corrupter -add 0 $TMPBG $TMPBG - i3lock -t -e -f -i $TMPBG - rm $TMPBG +set TMPBG /tmp/screen.png +scrot $TMPBG +corrupter -add 0 $TMPBG $TMPBG +i3lock -t -e -f -i $TMPBG +rm $TMPBG #+END_SRC * Polybar-launch (Deprecated) :noexport: @@ -1019,20 +1018,20 @@ while pgrep -u $UID -x polybar >/dev/null; do sleep 1; done Now that our system isn’t running polybar anymore, we’ll launch it again on all of our screens. By the way, I have two bars, so I’ll have to lauch them both. #+BEGIN_SRC bash - if type "xrandr"; then - for m in $(xrandr --query | grep " connected" | cut -d" " -f1); do - MONITOR=$m polybar --reload top & - MONITOR=$m polybar --reload bottom & - done - else - polybar --reload top & - polybar --reload bottom & - fi +if type "xrandr"; then + for m in $(xrandr --query | grep " connected" | cut -d" " -f1); do + MONITOR=$m polybar --reload top & + MONITOR=$m polybar --reload bottom & + done +else + polybar --reload top & + polybar --reload bottom & +fi #+END_SRC And we’re done! Let’s just launch a notification polybar has been relaunched. #+BEGIN_SRC bash - notify-send "Polybar restarted!" -a "polybar-launch" +notify-send "Polybar restarted!" -a "polybar-launch" #+END_SRC * Rofi utilities @@ -1049,7 +1048,7 @@ user’s sudo password. It is inspired by [[https://github.com/ODEX-TOS/tools/bl and with [[https://wiki.archlinux.org/index.php/Rofi][rofi]] support instead of [[https://wiki.archlinux.org/index.php/Dmenu][dmenu]]. As you can see, this is a oneliner if we ignore the initial shebang. This executable is pointed at by the #+BEGIN_SRC fish - rofi -dmenu -password -no-fixed-num-lines -p (printf $argv[1] | sed s/://) +rofi -dmenu -password -no-fixed-num-lines -p (printf $argv[1] | sed s/://) #+END_SRC ** awiki @@ -1072,17 +1071,17 @@ pipe that into rofi in dmenu mode in order to choose the page we want to display. By the way, setting the location of the HTML files will come in handy later. #+BEGIN_SRC fish - set WLOCATION /usr/share/doc/arch-wiki/html/en/ - set WPAGE (/bin/ls $WLOCATION | \ - sed -e 's/_/ /g' -e 's/\.html$//' -e 's|.*/\(.*\)|\1|' | \ - rofi -dmenu -p "Arch Wiki" -i) - set WPAGE (echo $WPAGE | sed -r 's/\s+/_/g') +set WLOCATION /usr/share/doc/arch-wiki/html/en/ +set WPAGE (/bin/ls $WLOCATION | \ + sed -e 's/_/ /g' -e 's/\.html$//' -e 's|.*/\(.*\)|\1|' | \ + rofi -dmenu -p "Arch Wiki" -i) +set WPAGE (echo $WPAGE | sed -r 's/\s+/_/g') #+END_SRC Now, all I need to do is to send this list into rofi and tell it to open the result with our favorite browser with ~xdg-open~. #+BEGIN_SRC fish - xdg-open $WLOCATION$WPAGE.html +xdg-open $WLOCATION$WPAGE.html #+END_SRC ** ConnectWifi :noexport: @@ -1095,18 +1094,18 @@ available WiFi networks. The first thing to do is to select the WiFi we want to connect to. We’ll use the ~nmcli c s~ command to get the list of the available networks, and we’ll chose one with ~rofi~. #+BEGIN_SRC fish - set SELECTEDWIFI (nmcli d w l | \ - egrep -o '([0-9A-F]{2}:){5}[0-9A-F]{2}\s*(.*)Infra' | \ - egrep -o '\s+(.*)\s+' | awk '{$1=$1}1' | \ - rofi -dmenu -p "Select your WiFi network") +set SELECTEDWIFI (nmcli d w l | \ +egrep -o '([0-9A-F]{2}:){5}[0-9A-F]{2}\s*(.*)Infra' | \ +egrep -o '\s+(.*)\s+' | awk '{$1=$1}1' | \ +rofi -dmenu -p "Select your WiFi network") #+END_SRC Now, if a network was selected, let’s attempt to connect to it. Otherwise, let’s just send a notification no network was selected. #+BEGIN_SRC fish - if test -z $SELECTEDWIFI - notify-send "No WiFi network selected" -u low && exit - end - nmcli c u $SELECTEDWIFI +if test -z $SELECTEDWIFI + notify-send "No WiFi network selected" -u low && exit +end +nmcli c u $SELECTEDWIFI #+END_SRC *** TODO fix it @@ -1123,7 +1122,7 @@ I wrote this very simple script in order to replace =dmenu= with rofi’s emulation of dmenu, since I prefer rofi’s appearance. It basically calls rofi’s dmenu emulation with the arguments initially passed to dmenu. #+BEGIN_SRC fish - rofi -dmenu $argv +rofi -dmenu $argv #+END_SRC ** Emoji picker @@ -1135,16 +1134,16 @@ The emoji picker is a simple fish script that uses rofi and [[file:~/.config/emo to provide a small, local search for emojis. Once the emoji is selected, it is copied to the clipboard using =xclipboard=. #+BEGIN_SRC fish - grep -v "#" ~/.config/emoji.txt | rofi -dmenu -p "Select emoji" -i | \ - awk '{print $1}' | tr -d '\n' | xclip -selection clipboard +grep -v "#" ~/.config/emoji.txt | rofi -dmenu -p "Select emoji" -i | \ +awk '{print $1}' | tr -d '\n' | xclip -selection clipboard #+END_SRC Also, let’s send a notification telling the user the emoji has been copied! #+BEGIN_SRC fish - set emoji (xclip -o -selection clipboard | tr -d '\n') - test -z "$emoji" && notify-send "No emoji copied" -u low && exit - set -a emoji "copied to clipboard" - notify-send -u low $emoji +set emoji (xclip -o -selection clipboard | tr -d '\n') +test -z "$emoji" && notify-send "No emoji copied" -u low && exit +set -a emoji "copied to clipboard" +notify-send -u low $emoji #+END_SRC It is inspired from [[https://www.youtube.com/watch?v=UCEXY46t3OA][this video]] from [[https://lukesmith.xyz/][Luke Smith]], rewritten in Fish. @@ -1168,7 +1167,7 @@ script. :CUSTOM_ID: Rofi-mount-Get_the_mountable_elements-24db7834 :END: #+BEGIN_SRC fish - begin +begin #+END_SRC What the script does first is detect everything that can be mounted. Between a @@ -1181,26 +1180,26 @@ set -l LFS Now, let’s detect the amount of mountable Android filesystems, and if any are detected, let’s read them into a global variable. #+BEGIN_SRC fish - set -l a (math (jmtpfs -l | wc -l) - 2) - test $a -ge 0 && jmtpfs -l 2> /dev/null | tail -n $a | read -zg anddrives +set -l a (math (jmtpfs -l | wc -l) - 2) +test $a -ge 0 && jmtpfs -l 2> /dev/null | tail -n $a | read -zg anddrives #+END_SRC We’ll do the same for external and internal drives and partitions that can be mounted here. #+BEGIN_SRC fish - lsblk -rpo "name,type,size,mountpoint" | \ - awk '$2=="part"&&$4==""{printf "%s (%s)\n",$1,$3}' | \ - read -zg usbdrives +lsblk -rpo "name,type,size,mountpoint" | \ +awk '$2=="part"&&$4==""{printf "%s (%s)\n",$1,$3}' | \ +read -zg usbdrives #+END_SRC Finally, we look for any CD drive that could be mounted on our device. #+BEGIN_SRC fish - blkid /dev/sr0 | awk '{print $1}' | sed 's/://' | read -z cddrives +blkid /dev/sr0 | awk '{print $1}' | sed 's/://' | read -z cddrives #+END_SRC And that’s the end of our first block! #+BEGIN_SRC fish - end +end #+END_SRC Alright, we’ll save what kind on drives we can mount in a temporary file called @@ -1208,22 +1207,22 @@ Alright, we’ll save what kind on drives we can mount in a temporary file calle with =touch=, like so. The =-f= flag on =rm= is here so we get no error if we try to delete a file that doesn’t exist (yet). #+BEGIN_SRC fish - set -g TMPDRIVES /tmp/drives - rm -f $TMPDRIVES - touch $TMPDRIVES +set -g TMPDRIVES /tmp/drives +rm -f $TMPDRIVES +touch $TMPDRIVES #+END_SRC Now, let’s write what type of drives we can mount in this temporary file. #+BEGIN_SRC fish - test -n "$usbdrives" && echo "USB" >> $TMPDRIVES - test -n "$cddrives" && echo "CD" >> $TMPDRIVES - test -n "$anddrives" && echo "Android" >> $TMPDRIVES +test -n "$usbdrives" && echo "USB" >> $TMPDRIVES +test -n "$cddrives" && echo "CD" >> $TMPDRIVES +test -n "$anddrives" && echo "Android" >> $TMPDRIVES #+END_SRC Now, we want to declare where to look for mount directories. For now, we’ll only look in =/media=, but you can add more if you wish. #+BEGIN_SRC fish - set -g basemount /media +set -g basemount /media #+END_SRC **** Get the mount point @@ -1233,7 +1232,7 @@ look in =/media=, but you can add more if you wish. Now, let’s declare a function that will allow us to chose the drive we want to mount. #+BEGIN_SRC fish - function getmount +function getmount #+END_SRC First, we want to get our mount point. We’ll run a =find= command on each of the @@ -1241,17 +1240,17 @@ directories listed in =$basemount= to look for folders on which our drive could be mounted. This list will be passed to rofi from which we will chose our mount point. #+BEGIN_SRC fish - set -g mp (for d in $basemount - find $d -maxdepth 5 -type d - end | rofi -dmenu -i -p 'Type in mount point.') +set -g mp (for d in $basemount + find $d -maxdepth 5 -type d +end | rofi -dmenu -i -p 'Type in mount point.') #+END_SRC We should verify that something has been actually selected, otherwise we should abort the script. #+BEGIN_SRC fish - if test -z $mp || test $mp = "" - return 1 - end +if test -z $mp || test $mp = "" + return 1 +end #+END_SRC Now, if the selected mount point does not exist, we’ll ask the user whether the @@ -1259,19 +1258,19 @@ directory should be created. If no, the script will abort. If yes, an attempt will be made at creating the directory as the user; if that fails, a new attempt will be made as sudo. #+BEGIN_SRC fish - if test ! -d $mp - switch (printf "No\\nYes" | rofi -dmenu -i -p "$mp does not exist. Create it?") - case 'Yes' - mkdir -p $mp || sudo -A mkdir -p $mp - case '*' - return 1 - end - end +if test ! -d $mp + switch (printf "No\\nYes" | rofi -dmenu -i -p "$mp does not exist. Create it?") + case 'Yes' + mkdir -p $mp || sudo -A mkdir -p $mp + case '*' + return 1 + end +end #+END_SRC Finally, let’s close the function #+BEGIN_SRC fish - end +end #+END_SRC **** Mount a USB drive, hard drive or partition @@ -1289,9 +1288,9 @@ Now, the first thing we want to do is select the partition we want to mount. Remember, we stored those in =$usbdrives= earlier, so let’s pipe them into rofi so we can chose from it. Also, =awk= will get their path in =/dev=. #+BEGIN_SRC fish - set -g chosen (echo $usbdrives | \ - rofi -dmenu -i -p "Mount which drive?" | \ - awk '{print $1}') +set -g chosen (echo $usbdrives | \ +rofi -dmenu -i -p "Mount which drive?" | \ +awk '{print $1}') #+END_SRC As usual after a user selection, let’s verify something has actually been @@ -1320,27 +1319,27 @@ switch (lsblk -no "fstype" $chosen) We have two named case: =vfat= filesystems. #+BEGIN_SRC fish - case "vfat" - sudo -A mount -t vfat $chosen $mp -o rw,umask=0000 +case "vfat" + sudo -A mount -t vfat $chosen $mp -o rw,umask=0000 #+END_SRC And =ntfs= filesystems. #+BEGIN_SRC fish - case "ntfs" - sudo -A mount -t ntfs $chosen $mp -o rw,umask=0000 +case "ntfs" + sudo -A mount -t ntfs $chosen $mp -o rw,umask=0000 #+END_SRC Else, we’ll let =mount= determine which filesystem is used by the partition (generally =ext4=). #+BEGIN_SRC fish - case '*' - sudo -A mount $chosen $mp +case '*' + sudo -A mount $chosen $mp #+END_SRC We’ll also run a =chown= on this newly mounted filesystem so the user can access it without any issues. #+BEGIN_SRC fish - sudo -A chown -R $USER:(id -g $USER) $mp +sudo -A chown -R $USER:(id -g $USER) $mp #+END_SRC Let’s close the switch block and send a notification the partition has been @@ -1386,22 +1385,22 @@ Android version it is running on, we either need to specify our device is USB connected in order to exchange files, or Android will explicitely ask us if it is OK for our computer to access it. Let’s inform the user of that. #+BEGIN_SRC fish - echo "OK" | \ - rofi -dmenu -i -p "Press (Allow) on your phone screen, or set your USB settings to allow file transfert" +echo "OK" | \ +rofi -dmenu -i -p "Press (Allow) on your phone screen, or set your USB settings to allow file transfert" #+END_SRC Now, let’s get the actual path of our Android filesystem we wish to mount, and let’s unmount the previous temporary filesystem. #+BEGIN_SRC fish - set newchosen (jmtpfs -l | grep $bus | awk '{print $1 $2}' | sed 's/,$//') - sudo -A umount $mp +set newchosen (jmtpfs -l | grep $bus | awk '{print $1 $2}' | sed 's/,$//') +sudo -A umount $mp #+END_SRC Now we cam mount the new filesystem and send a notification if everything went well. #+BEGIN_SRC fish - jmtpfs -device=$newchosen $mp && \ - notify-send -a "dmount" "🤖 Android Mounting" "Android device mounted to $mp." +jmtpfs -device=$newchosen $mp && \ +notify-send -a "dmount" "🤖 Android Mounting" "Android device mounted to $mp." #+END_SRC And now, we can close our function. @@ -1422,7 +1421,7 @@ function mountcd Now, let’s chose the CD drive we want to mount using =rofi=. #+BEGIN_SRC fish - set chosen (echo $cddrives | rofi -dmenu -i -p "Which CD drive?") +set chosen (echo $cddrives | rofi -dmenu -i -p "Which CD drive?") #+END_SRC We’ll also get the mountpoint thanks to the =getmount= function described @@ -1433,8 +1432,8 @@ getmount And finally, let’s mount it and send the notification everything went well. #+BEGIN_SRC fish - sudo -A mount $chosen $mp && \ - notify-send -a "dmount" "💿 CD mounting" "$chosen mounted." +sudo -A mount $chosen $mp && \ +notify-send -a "dmount" "💿 CD mounting" "$chosen mounted." #+END_SRC Finally, let’s close our function. @@ -1462,20 +1461,20 @@ switch (cat $TMPDRIVES | rofi -dmenu -i -p "Mount which drive?") If we chose the option "USB", we’ll mount a hard drive, partition or USB drive. In which case we’ll call the =mountusb= function. #+BEGIN_SRC fish - case "USB" - mountusb +case "USB" + mountusb #+END_SRC If we chose the "Android" option, the =mountandroid= function is called. #+BEGIN_SRC fish - case "Android" - mountandroid +case "Android" + mountandroid #+END_SRC Else if we chose the "CD" option, we’ll call the =mountcd= function. #+BEGIN_SRC fish - case "CD" - mountcd +case "CD" + mountcd #+END_SRC If nothing is selected, the function will naturally exit. Now, let’s close our @@ -1499,25 +1498,25 @@ switch (wc -l < $TMPDRIVES) If the file has no lines, i.e. it is empty, we have no mountable media. Let’s inform our user this is the case. #+BEGIN_SRC fish - case 0 - notify-send "No USB drive or Android device or CD detected" -a "dmount" +case 0 + notify-send "No USB drive or Android device or CD detected" -a "dmount" #+END_SRC If we only have one line, we have only one type of mountable media. We’ll pass this line to a second switch statement. #+BEGIN_SRC fish - case 1 - switch (cat $TMPDRIVES) +case 1 + switch (cat $TMPDRIVES) #+END_SRC This will allow the script to automatically detect what type of media it is, and mount the corresponding function. #+BEGIN_SRC fish - case "USB" - mountusb - case "Android" - mountandroid - case "CD" - mountCD +case "USB" + mountusb +case "Android" + mountandroid +case "CD" + mountCD #+END_SRC Let’s close this nested switch case. #+BEGIN_SRC fish @@ -1527,8 +1526,8 @@ end If we have more than one line, we’ll have to ask the user what type of media they want to mount. #+BEGIN_SRC fish - case '*' - asktype +case '*' + asktype #+END_SRC Now, let’s end our switch statement! @@ -1558,8 +1557,8 @@ partitions. First, we will need to list all the drives that can be safely unmounted. Let’s run this. #+BEGIN_SRC fish - set -g drives (lsblk -nrpo "name,type,size,mountpoint" | \ - awk '$2=="part"&&$4!~/\/boot|\/home$|SWAP/&&length($4)>1{printf "%s (%s)\n",$4,$3}') +set -g drives (lsblk -nrpo "name,type,size,mountpoint" | \ +awk '$2=="part"&&$4!~/\/boot|\/home$|SWAP/&&length($4)>1{printf "%s (%s)\n",$4,$3}') #+END_SRC Now, let’s get the android devices that are mounted. @@ -1579,16 +1578,16 @@ set -g undrivefile /tmp/undrives Let’s make sure we begin with a clean, empty file. #+BEGIN_SRC fish - rm -f $undrivefile - touch $undrivefile +rm -f $undrivefile +touch $undrivefile #+END_SRC Depending on if the related variables are set, write the different types of mounted drives in the temporary file. #+BEGIN_SRC fish - test -n "$drives" && echo "USB" >> $undrivefile - test -n "$cds" && echo "CD" >> $undrivefile - test -n "$androids" && echo "Android" >> $undrivefile +test -n "$drives" && echo "USB" >> $undrivefile +test -n "$cds" && echo "CD" >> $undrivefile +test -n "$androids" && echo "Android" >> $undrivefile #+END_SRC **** Unmount disk partitions @@ -1603,9 +1602,9 @@ function unmountusb Let’s chose the drive to unmount with rofi. #+BEGIN_SRC fish - set chosen (echo $drives | \ - rofi -dmenu -i -p "Unmount which drive?" | \ - awk '{print $1}') +set chosen (echo $drives | \ +rofi -dmenu -i -p "Unmount which drive?" | \ +awk '{print $1}') #+END_SRC Let’s verify if the user actually selected any drive. If no, let’s abort the @@ -1616,8 +1615,8 @@ test -z "$chosen" && exit 0 Now, let’s unmount the chosen drive and send a notification if it has been done. #+BEGIN_SRC fish - sudo -A umount $chosen && \ - notify-send "💻 USB unmounting" "$chosen unmounted." -a "dumount" +sudo -A umount $chosen && \ +notify-send "💻 USB unmounting" "$chosen unmounted." -a "dumount" #+END_SRC Now, let’s close the function. @@ -1642,14 +1641,14 @@ set chosen (echo $androids | rofi -dmenu -i -p "Unmount which device?") We’ll verify the user chose any device. #+BEGIN_SRC fish - test -z "$chosen" && exit 0 +test -z "$chosen" && exit 0 #+END_SRC If a device has been chosen, let’s unmount it and send a notification it has been successfuly unmounted. #+BEGIN_SRC fish - sudo -A umount -l $chosen && \ - notify-send "🤖 Android unmounting" "$chosen unmounted." -a "dumount" +sudo -A umount -l $chosen && \ +notify-send "🤖 Android unmounting" "$chosen unmounted." -a "dumount" #+END_SRC Finally, let’s close the function. @@ -1674,14 +1673,14 @@ set chosen (echo "$cds" | rofi -dmenu -i -p "Unmount which CD?") We’ll verify the user chose any device. #+BEGIN_SRC fish - test -z "$chosen" && exit 0 +test -z "$chosen" && exit 0 #+END_SRC If a drive has been chosen, let’s unmount it and send a notification it has been successfuly unmounted. #+BEGIN_SRC fish - sudo -A umount -l $chosen && \ - notify-send "💿 CD unmounting" "$chosen unmounted." -a "dumount" +sudo -A umount -l $chosen && \ +notify-send "💿 CD unmounting" "$chosen unmounted." -a "dumount" #+END_SRC Now, let’s close the function. @@ -1703,18 +1702,18 @@ function asktype Let’s create a switch statement to which will be passed the selection of the user from rofi. #+BEGIN_SRC fish - switch (cat $undrivefile | rofi -dmenu -i -p "Unmount which type of device?") +switch (cat $undrivefile | rofi -dmenu -i -p "Unmount which type of device?") #+END_SRC Three types of values can be returned: "USB", "CD", or "Android". These values will be used to launch their corresponding function. #+BEGIN_SRC fish - case 'USB' - unmountusb - case 'CD' - unmountcd - case 'Android' - unmountandroid +case 'USB' + unmountusb +case 'CD' + unmountcd +case 'Android' + unmountandroid #+END_SRC Let’s close the switch statement. @@ -1740,22 +1739,22 @@ switch (wc -l < $undrivefile) If the file containes no lines. i.e. it is empty, nothing is to be unmounted. Let’s inform the user of that. #+BEGIN_SRC fish - case 0 - notify-send "No USB drive or Android device or CD to unmount" -a "dumount" +case 0 + notify-send "No USB drive or Android device or CD to unmount" -a "dumount" #+END_SRC Else, if there is only one type of drive, we’ll automatically let our script choose based on the content of this sole line. #+BEGIN_SRC fish - case 1 - switch (cat $undrivefile) - case 'USB' - unmountusb - case 'CD' - unmountcd - case 'Android' - unmountandroid - end +case 1 + switch (cat $undrivefile) + case 'USB' + unmountusb + case 'CD' + unmountcd + case 'Android' + unmountandroid + end #+END_SRC And if there are more types than one, let’s ask the user. @@ -1787,54 +1786,54 @@ Let’s parse all the arguments passed to the script. If one of them is =--type= =-t= or =type=, the script will attempt to type the password to the text area already selected without pasting the password to the clipboard. #+BEGIN_SRC fish - for arg in $argv - switch $arg - case '--type' '-t' 'type' - set -g TYPE "yes" - case '*' - printf 'Unknown argument: %s\n.' $arg - exit 1 - end - end +for arg in $argv + switch $arg + case '--type' '-t' 'type' + set -g TYPE "yes" + case '*' + printf 'Unknown argument: %s\n.' $arg + exit 1 + end +end #+END_SRC Now, let’s get the list of the passwords that exist in our =pass= repository. #+BEGIN_SRC fish - set passwords (find $HOME/.password-store -type f -name "*.gpg" | \ - string replace -r ".*.password-store/" "" | \ - string replace -r ".gpg" "" | sort) +set passwords (find $HOME/.password-store -type f -name "*.gpg" | \ +string replace -r ".*.password-store/" "" | \ +string replace -r ".gpg" "" | sort) #+END_SRC Let the user choose which password they wish to select. #+BEGIN_SRC fish - set password (for elem in $passwords - echo $elem - end | rofi -dmenu -i -p "Select your password") +set password (for elem in $passwords + echo $elem +end | rofi -dmenu -i -p "Select your password") #+END_SRC Let’s verify we actually selected a password and not just exited. If no password was selected, let’s simply exit the script. #+BEGIN_SRC fish - if test -z $password - exit - end +if test -z $password + exit +end #+END_SRC Depending on the arguments passed earlier, we might want some different behavior. #+BEGIN_SRC fish :noweb yes - if test $TYPE = "yes" - <> - else - <> - end +if test $TYPE = "yes" + <> +else + <> +end #+END_SRC The default behavior is to copy the password to the clipboard for 45 seconds, so let’s do that. #+NAME: rofi-pass-copy #+BEGIN_SRC fish :noweb yes :tangle no - pass show -c $password 2> /dev/null +pass show -c $password 2> /dev/null #+END_SRC Else, if we passed =--type=, =-t= or =type= as an argument of the script, we @@ -1842,9 +1841,9 @@ want it to attempt to type our password in the currently selected text input. Let’s do that. #+NAME: rofi-pass-type #+BEGIN_SRC fish :noweb yes :tangle no - set -l IFS - <> - printf %s $pass | xvkbd -file - +set -l IFS +<> +printf %s $pass | xvkbd -file - #+END_SRC To correctly get the password from ~pass~, we need to parse the output and only @@ -1863,7 +1862,7 @@ This is just a simple wrapper around [[#ytdl-a-youtube-dl-wrapper-03bd63e0][ytdl rofi, which we’ll use first to retrieve the URL of the video we want to download, be it from YouTube or other website supported by ~youtube-dl~. #+BEGIN_SRC bash - URL=$(echo "Video to download:" | rofi -dmenu -i -p "Video to download:") +URL=$(echo "Video to download:" | rofi -dmenu -i -p "Video to download:") #+END_SRC Now, if the variable ~URL~ is not empty (i.e. the user specified a link and did @@ -1872,12 +1871,12 @@ send a notification saying the download is about to begin. When the ~ytdl~ process ends, we’ll also send a notification notifying the user on the success or failure of the download. #+BEGIN_SRC bash - if [ -n "$URL" ]; then - notify-send -u normal "YTDL" "Starting downloading\n$URL" - ytdl "$URL" \ - && notify-send -u normal "YTDL" "Finished downloading!" \ - || notify-send -u critical "YTDL" "Failed downloading\n$URL" - fi +if [ -n "$URL" ]; then + notify-send -u normal "YTDL" "Starting downloading\n$URL" + ytdl "$URL" \ + && notify-send -u normal "YTDL" "Finished downloading!" \ + || notify-send -u critical "YTDL" "Failed downloading\n$URL" +fi #+END_SRC * Wallpaper utilities @@ -1891,9 +1890,9 @@ or failure of the download. :END: This little tool sets a random wallpaper using xwallpaper. #+BEGIN_SRC sh - PAPESDIR=$HOME/Pictures/Wallpapers - PAPE=$(find $PAPESDIR -type f | sort -R | tail -1) - set-pape $PAPE +PAPESDIR=$HOME/Pictures/Wallpapers +PAPE=$(find $PAPESDIR -type f | sort -R | tail -1) +set-pape $PAPE #+END_SRC ** Select wallpaper @@ -1904,8 +1903,8 @@ This little tool sets a random wallpaper using xwallpaper. This script is base on what ~sxiv~ can do as an image viewer as well as xwallpaper. #+BEGIN_SRC sh - PAPE=$(sxiv -orbft ~/Pictures/Wallpapers/*) - set-pape $PAPE +PAPE=$(sxiv -orbft ~/Pictures/Wallpapers/*) +set-pape $PAPE #+END_SRC ** Set a wallpaper @@ -1919,11 +1918,11 @@ provided wallpaper exists and if it is an image. If both requirements are met, the path to this image is then stored in ~$XDG_CACHE_HOME/wallpaper~, or if this variable is empty in ~$HOME/.cache/wallpaper~. #+BEGIN_SRC sh - CACHEFILE=$([ -n "$XDG_CACHE_HOME" ] && echo $XDG_CACHE_HOME/wallpaper || echo $HOME/.cache/wallpaper) - [[ -f $1 ]] && \ - grep image <(file -b --mime-type $1) && \ - echo $1 > $CACHEFILE \ - && xwallpaper --zoom $1 +CACHEFILE=$([ -n "$XDG_CACHE_HOME" ] && echo $XDG_CACHE_HOME/wallpaper || echo $HOME/.cache/wallpaper) +[[ -f $1 ]] && \ + grep image <(file -b --mime-type $1) && \ + echo $1 > $CACHEFILE \ + && xwallpaper --zoom $1 #+END_SRC * Weather @@ -1936,10 +1935,10 @@ weather forecast in the terminal. By default, I want the request to be about the city I live in, but it is also possible for the script to accept as its arguments a search inquiry. #+BEGIN_SRC fish - if count $argv > /dev/null - set -l SEARCH (string join '+' $argv) - curl http://v2.wttr.in/~$SEARCH - else - curl http://v2.wttr.in/Aubervilliers - end +if count $argv > /dev/null + set -l SEARCH (string join '+' $argv) + curl http://v2.wttr.in/~$SEARCH +else + curl http://v2.wttr.in/Aubervilliers +end #+END_SRC diff --git a/org/config/bootstrap.org b/org/config/bootstrap.org index 0dac5f2..fd57a66 100644 --- a/org/config/bootstrap.org +++ b/org/config/bootstrap.org @@ -47,9 +47,9 @@ partition is 16GB large. :END: When you boot into the live ISO, execute the following command: #+BEGIN_SRC sh - pacman -Sy reflector - reflector -c FR -c DE -c BE -l 200 -p http -p https --sort rate \ - --save /etc/pacman.d/mirrorlist --verbose +pacman -Sy reflector +reflector -c FR -c DE -c BE -l 200 -p http -p https --sort rate \ + --save /etc/pacman.d/mirrorlist --verbose #+END_SRC This will update the packages from your live ISO, and you will get the best @@ -67,14 +67,14 @@ how the distro works, I just want to be able to install my distro quickly now. I’ll need to download the script with ~wget~, but apparently it isn’t installed by default on Arch ISOs anymore, so I’ll need to install it. #+BEGIN_SRC sh - pacman -S wget +pacman -S wget #+END_SRC Now, let’s grab the script. You can check it on [[https://github.com/matmoul/archfi][Github]]. #+BEGIN_SRC sh - wget archfi.sf.net/archfi - # Or from matmoul.github.io/archfi if SourceForge is down - sh archfi +wget archfi.sf.net/archfi +# Or from matmoul.github.io/archfi if SourceForge is down +sh archfi #+END_SRC Then, follow the instructions and install Arch Linux. Take the opportunity to @@ -90,28 +90,32 @@ your computer. :HEADER-ARGS:fish: :tangle ~/.config/yadm/bootstrap :shebang "#!/usr/bin/fish" :exports code :mkdirp yes :CUSTOM_ID: Execute_bootstrap-e37054ef :END: -The first thing I will do is add the [[https://github.com/archlinuxcn/repo][ArchLinuxCN]] repository so I can get access -to ~paru~. +The first thing I will do is add the [[https://aur.chaotic.cx/][Chaotic AUR]] repository so I can +get access to ~paru~ as well as some AUR packages without the need of an +AUR helper (ironic considering ~paru~ is one).. #+BEGIN_SRC sh - printf '[archlinuxcn]\nServer = https://repo.archlinuxcn.org/$arch\n' | sudo tee -a /etc/pacman.conf +sudo pacman-key --recv-key 3056513887B78AEB --keyserver keyserver.ubuntu.com +sudo pacman-key --lsign-key 3056513887B78AEB +sudo pacman -U 'https://cdn-mirror.chaotic.cx/chaotic-aur/chaotic-keyring.pkg.tar.zst' 'https://cdn-mirror.chaotic.cx/chaotic-aur/chaotic-mirrorlist.pkg.tar.zst' +printf '[chaotic-aur]\nServer = /etc/pacman.d/chaotic-mirrorlist\n' | sudo tee -a /etc/pacman.conf #+END_SRC I can now install ~fish~, ~git~, and ~paru~: #+BEGIN_SRC sh - sudo pacman -S fish git paru +sudo pacman -S fish git paru #+END_SRC And now that ~paru~ is available, we can install ~yadm~: #+BEGIN_SRC sh - paru -S yadm +paru -S yadm #+END_SRC ~yadm~ comes with a very handy feature: its bootstrap script. It can be executed automatically once the dotfiles are cloned with yadm: #+BEGIN_SRC sh - yadm clone https://labs.phundrak.com/phundrak/dotfiles - # or if labs.phundrak.com is down or too slow for you - #yadm clone https://github.com/phundrak/dotfiles +yadm clone https://labs.phundrak.com/phundrak/dotfiles +# or if labs.phundrak.com is down or too slow for you +#yadm clone https://github.com/phundrak/dotfiles #+END_SRC Let’s take a look at what it does. @@ -123,11 +127,11 @@ Let’s take a look at what it does. Some private files are stored encrypted in the repository of my yadm dotfiles. I will need them later on during the bootstrap execution. #+BEGIN_SRC fish - if test "$USER" = 'phundrak' - yadm decrypt - else - whiptail --yesno "Decrypt private files?" 8 40 && yadm decrypt - end +if test "$USER" = 'phundrak' + yadm decrypt +else + whiptail --yesno "Decrypt private files?" 8 40 && yadm decrypt +end #+END_SRC ** Get a correct keyboard layout @@ -140,24 +144,24 @@ or the American QWERTY layout, so I make it so the Menu key switches for me my layout between these three. This makes it so my xorg configuration of my keyboard looks like this: #+BEGIN_SRC fish - set keyboardconf \ - 'Section "InputClass" - Identifier "system-keyboard" - MatchIsKeyboard "on" - Option "XkbLayout" "fr" - Option "XkbModel" "pc104" - Option "XkbVariant" "bepo_afnor" - Option "XkbOptions" "caps:ctrl_modifier" - EndSection' +set keyboardconf \ +'Section "InputClass" + Identifier "system-keyboard" + MatchIsKeyboard "on" + Option "XkbLayout" "fr" + Option "XkbModel" "pc104" + Option "XkbVariant" "bepo_afnor" + Option "XkbOptions" "caps:ctrl_modifier" +EndSection' #+END_SRC So, let’s ask the user if they want to set it as their keyboard configuration. #+BEGIN_SRC fish - printf "\n# Set keyboard layout #########################################################\n\n" - whiptail --yesno "Would you like to set your keyboard layout to the bépo layout?" 8 55 - if test $status -eq 0 - echo $keyboardconf | sudo tee /etc/X11/xorg.conf.d/00-keyboard.conf - end +printf "\n# Set keyboard layout #########################################################\n\n" +whiptail --yesno "Would you like to set your keyboard layout to the bépo layout?" 8 55 +if test $status -eq 0 + echo $keyboardconf | sudo tee /etc/X11/xorg.conf.d/00-keyboard.conf +end #+END_SRC ** Set our locale @@ -167,12 +171,12 @@ So, let’s ask the user if they want to set it as their keyboard configuration. I use two main locales, the French and US UTF-8 locales, and I like to keep the Japanese locale activated just in case. #+BEGIN_SRC fish - set mylocales "en_US.UTF-8 UTF-8" "fr_FR.UTF-8 UTF-8" "ja_JP.UTF-8 UTF-8" +set mylocales "en_US.UTF-8 UTF-8" "fr_FR.UTF-8 UTF-8" "ja_JP.UTF-8 UTF-8" #+END_SRC I’ll let the user accept them one by one. #+BEGIN_SRC fish - printf "\n# Set locale ##################################################################\n\n" +printf "\n# Set locale ##################################################################\n\n" for item in $mylocales whiptail --yesno "Set the \"$item\" locale?" 8 40 @@ -184,29 +188,29 @@ I’ll let the user accept them one by one. This is my configuration I usually use when it comes to my locale. #+BEGIN_SRC fish - set localeconf "LANG=en_DK.UTF-8 - LC_COLLATE=C - LC_NAME=fr_FR.UTF-8 - LC_IDENTIFICATION=fr_FR.UTF-8 - LC_TELEPHONE=fr_FR.UTF-8 - LC_MONETARY=fr_FR.UTF-8 - LC_PAPER=fr_FR.UTF-8 - LC_ADDRESS=fr_FR.UTF-8 - LC_MEASUREMENT=fr_FR.UTF-8" +set localeconf "LANG=en_DK.UTF-8 +LC_COLLATE=C +LC_NAME=fr_FR.UTF-8 +LC_IDENTIFICATION=fr_FR.UTF-8 +LC_TELEPHONE=fr_FR.UTF-8 +LC_MONETARY=fr_FR.UTF-8 +LC_PAPER=fr_FR.UTF-8 +LC_ADDRESS=fr_FR.UTF-8 +LC_MEASUREMENT=fr_FR.UTF-8" #+END_SRC Let’s set it as our system’s locale if the user whishes to. #+BEGIN_SRC fish - whiptail --yesno "Do you agree to have the following locale set?\n\n $localeconf" 20 43 - if test $status -eq 0 - echo $localeconf | sudo tee /etc/locale.conf - end +whiptail --yesno "Do you agree to have the following locale set?\n\n $localeconf" 20 43 +if test $status -eq 0 + echo $localeconf | sudo tee /etc/locale.conf +end #+END_SRC Now we can generate our locale! #+BEGIN_SRC fish - printf "\n# Generate locale #############################################################\n\n" - sudo locale-gen +printf "\n# Generate locale #############################################################\n\n" +sudo locale-gen #+END_SRC ** Create some folders @@ -216,9 +220,9 @@ Now we can generate our locale! Let’s create some folders we might need for mounting our drives, Android devices and CDs. #+BEGIN_SRC fish - printf "\n# Create directories for mounting #############################################\n\n" - sudo mkdir -p /mnt/{USB,CD,Android} - sudo chown $USER:(id -g $USER) /mnt/{USB,CD,Android} +printf "\n# Create directories for mounting #############################################\n\n" +sudo mkdir -p /mnt/{USB,CD,Android} +sudo chown $USER:(id -g $USER) /mnt/{USB,CD,Android} #+END_SRC ** Set user’s shell to fish @@ -227,11 +231,11 @@ and CDs. :END: First of all, the bootstrap shell will set the user’s shell to fish. #+BEGIN_SRC fish - printf "\n# Set fish as the default shell ###############################################\n\n" - whiptail --yesno "Set the current user’s default shell to fish?" 8 50 - if test $status -eq 0 -a ! "$SHELL" = '/usr/bin/fish' - chsh -s /usr/bin/fish - end +printf "\n# Set fish as the default shell ###############################################\n\n" +whiptail --yesno "Set the current user’s default shell to fish?" 8 50 +if test $status -eq 0 -a ! "$SHELL" = '/usr/bin/fish' + chsh -s /usr/bin/fish +end #+END_SRC ** Install basic packages @@ -240,49 +244,49 @@ First of all, the bootstrap shell will set the user’s shell to fish. :END: Let’s set in a custom varible what packages we’ll be needing. #+BEGIN_SRC fish - set PACKAGES \ - acpi acpilight adobe-source-han-sans-jp-fonts arc-gtk-theme asar ascii \ - aspell-en aspell-fr awesome awesome-terminal-fonts awesome-freedesktop-git \ - base-devel bashtop bat biber bitwarden-bin bluez-firmware bluez-utils bzip2 \ - chicken chromium clisp corrupter-git cppcheck cppreference \ - cppreference-devhelp cpupower discord-canary discount docker docker-compose \ - dockerfile-language-server-bin doxygen emacs emacs-org-mode exa exfat-utils \ - farbfeld fd ffmpegthumbnailer findutils firefox flake8 flat-remix-gtk freeglut \ - fzf gcc-libs gdb gimp gnome-disk-utility gnome-epub-thumbnailer gnu-free-fonts \ - gnuplot go go-tools golangci-lint-bin graphviz htop hugo i3lock-color \ - inetutils isync inter-font javascript-typescript-langserver js-beautify \ - jfsutils jmtpfs kitty lain-git libxft-bgra linux-headers lldb logrotate meson \ - minted man-db man-pages mpc mpd mpd-rich-presence-discord-git mpv mupdf-tools \ - nano ncdu ncmpcpp nemo-fileroller nemo-preview neofetch netctl \ - network-manager-applet networkmanager networkmanager-openvpn \ - nm-connection-editor nodejs-vmd nomacs nordic-theme-git nordvpn-bin \ - noto-fonts-emoji npm ntfs-3g numlockx obs-studio openssh otf-fandol \ - otf-ipafont p7zip pacman-contrib pandoc-bin pass pavucontrol pdfpc picom-git \ - powerline-fonts prettier pulseaudio-bluetooth python-autoflake python-epc \ - python-importmagic python-language-server python-nose python-pip python-poetry \ - python-ptvsd python-pytest qt5-imageformats qemu r raw-thumbnailer reflector \ - ripgrep rofi rsync rtv ruby-rb-fsevent ruby-sass rustup samba scrot sent \ - shadow siji-git simplescreenrecorder sshfs sxiv texlive-bibtexextra \ - texlive-fontsextra texlive-formatsextra texlive-humanities \ - texlive-langjapanese texlive-pictures texlive-pstricks texlive-publishers \ - texlive-science tldr tmux tree ttf-arphic-uming ttf-baekmuk ttf-charis-sil \ - ttf-dejavu ttf-google-fonts-opinionated-git ttf-hanazono ttf-joypixels \ - ttf-koruri ttf-liberation ttf-monapo ttf-sazanami ttf-tibetan-machine \ - typescript typescript-language-server-bin unicode-emoji unrar usbutils \ - valgrind vscode-css-languageserver-bin vscode-html-languageserver-bin w3m wget \ - x11-ssh-askpass xclip xdg-user-dirs-gtk xfce-polkit xidlehook xfsprogs \ - xorg-drivers xorg-server xorg-xinit xss-lock xvkbd xwallpaper \ - yaml-language-server-bin zeal +set PACKAGES \ +acpi acpilight adobe-source-han-sans-jp-fonts arc-gtk-theme asar ascii \ +aspell-en aspell-fr awesome awesome-terminal-fonts awesome-freedesktop-git \ +base-devel bashtop bat biber bitwarden-bin bluez-firmware bluez-utils bzip2 \ +chicken chromium clisp corrupter-git cppcheck cppreference \ +cppreference-devhelp cpupower discord-canary discount docker docker-compose \ +dockerfile-language-server-bin doxygen emacs emacs-org-mode exa exfat-utils \ +farbfeld fd ffmpegthumbnailer findutils firefox flake8 flat-remix-gtk freeglut \ +fzf gcc-libs gdb gimp gnome-disk-utility gnome-epub-thumbnailer gnu-free-fonts \ +gnuplot go go-tools golangci-lint-bin graphviz htop hugo i3lock-color \ +inetutils isync inter-font javascript-typescript-langserver js-beautify \ +jfsutils jmtpfs kitty lain-git libxft-bgra linux-headers lldb logrotate meson \ +minted man-db man-pages mpc mpd mpd-rich-presence-discord-git mpv mupdf-tools \ +nano ncdu ncmpcpp nemo-fileroller nemo-preview neofetch netctl \ +network-manager-applet networkmanager networkmanager-openvpn \ +nm-connection-editor nodejs-vmd nomacs nordic-theme-git nordvpn-bin \ +noto-fonts-emoji npm ntfs-3g numlockx obs-studio openssh otf-fandol \ +otf-ipafont p7zip pacman-contrib pandoc-bin pass pavucontrol pdfpc picom-git \ +powerline-fonts prettier pulseaudio-bluetooth python-autoflake python-epc \ +python-importmagic python-language-server python-nose python-pip python-poetry \ +python-ptvsd python-pytest qt5-imageformats qemu r raw-thumbnailer reflector \ +ripgrep rofi rsync rtv ruby-rb-fsevent ruby-sass rustup samba scrot sent \ +shadow siji-git simplescreenrecorder sshfs sxiv texlive-bibtexextra \ +texlive-fontsextra texlive-formatsextra texlive-humanities \ +texlive-langjapanese texlive-pictures texlive-pstricks texlive-publishers \ +texlive-science tldr tmux tree ttf-arphic-uming ttf-baekmuk ttf-charis-sil \ +ttf-dejavu ttf-google-fonts-opinionated-git ttf-hanazono ttf-joypixels \ +ttf-koruri ttf-liberation ttf-monapo ttf-sazanami ttf-tibetan-machine \ +typescript typescript-language-server-bin unicode-emoji unrar usbutils \ +valgrind vscode-css-languageserver-bin vscode-html-languageserver-bin w3m wget \ +x11-ssh-askpass xclip xdg-user-dirs-gtk xfce-polkit xidlehook xfsprogs \ +xorg-drivers xorg-server xorg-xinit xss-lock xvkbd xwallpaper \ +yaml-language-server-bin zeal #+END_SRC These are the minimum I would have in my own installation. You can edit it however you want. Let’s install those. #+BEGIN_SRC fish - printf "\n# Installing needed packages ##################################################\n\n" - sudo pacman -Syu - for pkg in $PACKAGES - paru -S --needed $pkg - end +printf "\n# Installing needed packages ##################################################\n\n" +sudo pacman -Syu +for pkg in $PACKAGES + paru -S --needed $pkg +end #+END_SRC ** Tangle configuration files from Org files @@ -308,9 +312,9 @@ need to create: #+NAME: gen-dirs-tangle #+BEGIN_SRC emacs-lisp :var dirs=dirs-tangled-files - (mapconcat (lambda (x) (format "mkdir -p %s" (car x))) - dirs - "\n") +(mapconcat (lambda (x) (format "mkdir -p %s" (car x))) + dirs + "\n") #+END_SRC #+RESULTS[a95e25a5f3ac91b1f884b39dde38e3b51366b188]: gen-dirs-tangle @@ -331,7 +335,7 @@ mkdir -p $HOME/org/capture Our code to generate such directories looks like this: #+BEGIN_SRC fish :noweb yes - <> +<> #+END_SRC The next step is to tangle all the Org files. Here is the list of files that are @@ -350,13 +354,13 @@ to be tangled: #+NAME: generate-tangle #+BEGIN_SRC emacs-lisp :var files=tangled-files[,0] - (mapconcat (lambda (x) (concat - (format "printf '\\n\\n==== Tangling %s\\n\\n' && \\\n" x) - (concat "emacs -q --batch --eval '(require \\'ob-tangle)' \\\n" - "--eval '(setq org-confirm-babel-evaluate nil)' \\\n" - (format "--eval '(org-babel-tangle-file \"~/org/config/%s\")'\n" x)))) - files - "\n") +(mapconcat (lambda (x) (concat + (format "printf '\\n\\n==== Tangling %s\\n\\n' && \\\n" x) + (concat "emacs -q --batch --eval '(require \\'ob-tangle)' \\\n" + "--eval '(setq org-confirm-babel-evaluate nil)' \\\n" + (format "--eval '(org-babel-tangle-file \"~/org/config/%s\")'\n" x)))) + files + "\n") #+END_SRC #+RESULTS[87a25d6c524e8d1346452c54aa42ac3ac09d94cf]: generate-tangle @@ -403,8 +407,8 @@ emacs -q --batch --eval '(require \'ob-tangle)' \ #+end_example #+BEGIN_SRC fish :noweb yes - printf "\n# Tangling org files ##########################################################\n\n" - <> +printf "\n# Tangling org files ##########################################################\n\n" +<> #+END_SRC ** Setting up Emacs: Installing Spacemacs @@ -418,19 +422,19 @@ cloned within our =~/.config/emacs= directory, and git won’t let us clone Spacemacs in an already existing and non-empty directory. To make sure it isn’t one, let’s delete any potentially existing =~/.config/emacs= directory: #+BEGIN_SRC fish - printf "\n# Installing Spacemacs ########################################################\n\n" - rm -rf $HOME/.config/emacs $HOME/.emacs* .spacemacs +printf "\n# Installing Spacemacs ########################################################\n\n" +rm -rf $HOME/.config/emacs $HOME/.emacs* .spacemacs #+END_SRC Now we can clone Spacemacs: #+BEGIN_SRC fish - git clone --branch develop https://github.com/syl20bnr/spacemacs ~/.config/emacs +git clone --branch develop https://github.com/syl20bnr/spacemacs ~/.config/emacs #+END_SRC And we can restore what might have been deleted in our =~/.emacs.d/private= directory: #+BEGIN_SRC fish - yadm checkout -- ~/.config/emacs/private/ +yadm checkout -- ~/.config/emacs/private/ #+END_SRC ** Set up dotfiles’ git repository @@ -444,26 +448,26 @@ directory: This line in the bootstrap script will test if the current user is using my username. If yes, it’s probably me. #+BEGIN_SRC fish - if test "$USER" = 'phundrak' +if test "$USER" = 'phundrak' #+END_SRC If it is me installing and using these dotfiles, I want the remotes of my dotfiles to be set to ssh remotes using my ssh keys. #+BEGIN_SRC fish - printf "\n# Update yadm’s remotes #######################################################\n\n" - yadm remote set-url origin git@labs.phundrak.com:phundrak/dotfiles.git - yadm remote add github git@github.com:phundrak/dotfiles.git +printf "\n# Update yadm’s remotes #######################################################\n\n" +yadm remote set-url origin git@labs.phundrak.com:phundrak/dotfiles.git +yadm remote add github git@github.com:phundrak/dotfiles.git #+END_SRC I will also want to decrypt my encrypted files, such as said ssh keys. #+BEGIN_SRC fish - printf "\n# Decrypt encrypted dotfiles ##################################################\n\n" - yadm decrypt +printf "\n# Decrypt encrypted dotfiles ##################################################\n\n" +yadm decrypt #+END_SRC Finally, let’s close this ~if~ statement. #+BEGIN_SRC fish - end +end #+END_SRC *** Update our submodules @@ -473,8 +477,8 @@ Finally, let’s close this ~if~ statement. Now we can download the various dependencies of our dotfiles. To do so, let’s run the following command: #+BEGIN_SRC fish - printf "\n# Getting yadm susbmodules ####################################################\n\n" - yadm submodule update --init --recursive +printf "\n# Getting yadm susbmodules ####################################################\n\n" +yadm submodule update --init --recursive #+END_SRC ** Enable some services @@ -491,14 +495,14 @@ them. This service enables time syncing with the NTP protocol, so I can be sure my computer’s time is correct. The service first needs to be enabled: #+BEGIN_SRC fish - printf "\n# Enabling timesync ###########################################################\n\n" - sudo systemctl enable --now systemd-timesyncd +printf "\n# Enabling timesync ###########################################################\n\n" +sudo systemctl enable --now systemd-timesyncd #+END_SRC Now, let systemd know I want to use the NTP protocol to keep my computer’s time synced. #+BEGIN_SRC fish - sudo timedatectl set-ntp true +sudo timedatectl set-ntp true #+END_SRC *** Docker @@ -507,17 +511,17 @@ synced. :END: First, let’s activate Docker on startup. #+BEGIN_SRC fish - printf "\n# Enabling and starting Docker ################################################\n\n" - sudo systemctl enable --now docker +printf "\n# Enabling and starting Docker ################################################\n\n" +sudo systemctl enable --now docker #+END_SRC Now, if we wish it, we can be added to the =docker= group so we won’t have to type =sudo= each time we call Docker or Docker Compose. #+BEGIN_SRC fish - read --prompt "echo 'Do you wish to be added to the `docker` group? (Y/n): ' " -l adddockergroup - if test $adddockergroup = 'y' || test $adddockergroup = "Y" || test $adddockergroup = '' - sudo usermod -aG docker $USER - end +read --prompt "echo 'Do you wish to be added to the `docker` group? (Y/n): ' " -l adddockergroup +if test $adddockergroup = 'y' || test $adddockergroup = "Y" || test $adddockergroup = '' + sudo usermod -aG docker $USER +end #+END_SRC *** Emacs @@ -529,8 +533,8 @@ in. However, the service won’t be started immediately, I personally prefer to start a standalone instance in which installing and compiling the Emacs packages will happen, and then once that is done I will start the service. #+BEGIN_SRC fish - printf "\n# Enabling Emacs as user service ##############################################\n\n" - systemctl --user enable emacs +printf "\n# Enabling Emacs as user service ##############################################\n\n" +systemctl --user enable emacs #+END_SRC *** Mpd @@ -540,9 +544,9 @@ will happen, and then once that is done I will start the service. Mpd will also use as a user service in order to get rid of some lines of code in my configuration. #+BEGIN_SRC fish - printf "\n# Enabling Mpd as a user service ##############################################\n\n" - mkdir -p ~/.config/mpd/playlists - systemctl --user enable --now mpd +printf "\n# Enabling Mpd as a user service ##############################################\n\n" +mkdir -p ~/.config/mpd/playlists +systemctl --user enable --now mpd #+END_SRC *** SSH server @@ -552,11 +556,11 @@ my configuration. Maybe we want to activate an SSH server on our machine. If so, we can enable it. Let’s ask the question. #+BEGIN_SRC fish - whiptail --yesno 'Do you want to activate the ssh server?' 8 50 - if test $status -eq 0 - printf "\n# Enabling ssh server #########################################################\n\n" - sudo systemctl enable --now sshd - end +whiptail --yesno 'Do you want to activate the ssh server?' 8 50 +if test $status -eq 0 + printf "\n# Enabling ssh server #########################################################\n\n" + sudo systemctl enable --now sshd +end #+END_SRC *** Acpilight @@ -568,7 +572,7 @@ actually no service to enable here, but we must ensure the user is part of the ~video~ group so we can modify the brightness of our screen without using ~sudo~. #+BEGIN_SRC fish - sudo usermod -aG video $USER +sudo usermod -aG video $USER #+END_SRC *** NordVPN @@ -579,7 +583,7 @@ Thanks to the AUR package ~nordvpn-bin~, I no longer have to manually maintain my VPN connections with OpenVPN. However, it requires a service that we should activate: #+BEGIN_SRC fish - sudo systemctl enable --now nordvpnd +sudo systemctl enable --now nordvpnd #+END_SRC Let’s also set its default protocol to UDP. This will allow me to use any port @@ -587,7 +591,7 @@ while connected to any WiFi as long as the 443 port is available. Because yes, I do connect to a WiFi that blocks some important ports, such as the IMAP and SMTP ports. Thanks University of Paris 8 for being SO paranoid. #+BEGIN_SRC fish - nordvpn s protocol tcp +nordvpn s protocol tcp #+END_SRC ** Symlink some system config files @@ -596,16 +600,16 @@ ports. Thanks University of Paris 8 for being SO paranoid. :END: We have some files in [[file:ect/][etc/]] that are to be symlinked to =/etc=. #+BEGIN_SRC fish - for f in (find ~/.etc -type f) - set dest (echo $f | sed -n 's|^.*etc\(.*\)$|/etc\1|p') - sudo ln -s $f $dest - end +for f in (find ~/.etc -type f) + set dest (echo $f | sed -n 's|^.*etc\(.*\)$|/etc\1|p') + sudo ln -s $f $dest +end #+END_SRC Let’s also symlink the ~plock~ script ([[file:bin.org::#Lock-635fcb38][source here]]) to ~/usr/bin~ so ~xss-lock~ can find it. #+BEGIN_SRC fish - sudo ln -s (which plock) /usr/bin/plock +sudo ln -s (which plock) /usr/bin/plock #+END_SRC ** Install packages from git @@ -614,7 +618,7 @@ can find it. :END: Now, let’s install some packages from git directly. #+BEGIN_SRC fish - mkdir -p ~/fromGIT +mkdir -p ~/fromGIT #+END_SRC *** Reveal.JS @@ -624,9 +628,9 @@ Now, let’s install some packages from git directly. I sometimes use Reveal.JS to make presentations, and I set its location in my [[file:.spacemacs][dotspacemacs]] file to be in =~/fromGIT=, so let’s clone it there. #+BEGIN_SRC fish - printf "\n# Install Reveal.JS ###########################################################\n\n" - cd ~/fromGIT - git clone https://github.com/hakimel/reveal.js.git +printf "\n# Install Reveal.JS ###########################################################\n\n" +cd ~/fromGIT +git clone https://github.com/hakimel/reveal.js.git #+END_SRC ** Install Rust @@ -641,14 +645,14 @@ When using Rust, I bounce between two toolchains, the ~stable~ toolchain and the ~nightly~ toolchain, although I try to stick with Rust Stable. To install them, I will use ~rustup~ which has already been installed previously. #+BEGIN_SRC fish - printf "\n# Install the rust toolchains, nightly is the default one #####################\n\n" - rustup default stable +printf "\n# Install the rust toolchains, nightly is the default one #####################\n\n" +rustup default stable #+END_SRC This will both download the stable toolchain and set it as the default one. Now to install the nightly toolchain, let’s run this: #+BEGIN_SRC fish - rustup toolchain install nightly +rustup toolchain install nightly #+END_SRC *** Install some utilities @@ -658,8 +662,8 @@ to install the nightly toolchain, let’s run this: We’ll need some utilities when developing Rust from Emacs, namely ~rustfmt~ and ~racer~. Let’s install them with ~cargo~. #+BEGIN_SRC fish - printf "\n# Add rust utilities ##########################################################\n\n" - cargo install rustfmt racer +printf "\n# Add rust utilities ##########################################################\n\n" +cargo install rustfmt racer #+END_SRC We will also need some components for development purposes. @@ -672,9 +676,9 @@ We will also need some components for development purposes. #+NAME: rust-components-gen #+BEGIN_SRC emacs-lisp :var components=rust-components-table[,0] - (mapconcat (lambda (x) (format "rustup component add %s" x)) - components - "\n") +(mapconcat (lambda (x) (format "rustup component add %s" x)) + components + "\n") #+END_SRC #+RESULTS[b3935b1c09d86fe506b43670f52960306a1e9809]: @@ -684,7 +688,7 @@ We will also need some components for development purposes. Here is the code to do so: #+BEGIN_SRC fish :noweb yes - <> +<> #+END_SRC ** Install some python packages @@ -703,8 +707,8 @@ working. #+NAME: python-packages-gen #+BEGIN_SRC emacs-lisp :var packages=python-packages-table[,0] - (format "pip install --user %s" - (string-join packages " ")) +(format "pip install --user %s" + (string-join packages " ")) #+END_SRC #+RESULTS[29652be1076ffac01e34189067efa8fe9abda9d9]: python-packages-gen @@ -712,8 +716,8 @@ working. Let’s install them locally for our user. #+BEGIN_SRC fish :noweb yes - printf "\n# Installing Python packages ##################################################\n\n" - <> +printf "\n# Installing Python packages ##################################################\n\n" +<> #+END_SRC ** Set up Chicken (Scheme interpreter/compiler) @@ -723,14 +727,14 @@ Let’s install them locally for our user. Chicken needs to be set up before being used. First, we need to install its documentation. #+BEGIN_SRC fish - printf "\n# Setting up Chicken ##########################################################\n\n" - chicken-install -s apropos chicken-doc +printf "\n# Setting up Chicken ##########################################################\n\n" +chicken-install -s apropos chicken-doc #+END_SRC Then, we’ll complete the documentation like so: #+BEGIN_SRC fish - cd (chicken-csi -b -e "(import (chicken platform))" -p "(chicken-home)") - curl https://3e8.org/pub/chicken-doc/chicken-doc-repo.tgz | sudo tar zx +cd (chicken-csi -b -e "(import (chicken platform))" -p "(chicken-home)") +curl https://3e8.org/pub/chicken-doc/chicken-doc-repo.tgz | sudo tar zx #+END_SRC ** Set up our fish shell @@ -746,8 +750,8 @@ order to improve the user experience. :END: We will be using ~fisher~ as our extensions manager for Fish. Let’s install it. #+BEGIN_SRC fish - printf "\n# Installing fisher ###########################################################\n\n" - curl https://git.io/fisher --create-dirs -sLo ~/.config/fish/functions/fisher.fish +printf "\n# Installing fisher ###########################################################\n\n" +curl https://git.io/fisher --create-dirs -sLo ~/.config/fish/functions/fisher.fish #+END_SRC *** Install our extensions @@ -770,9 +774,9 @@ I generally use the following extensions in my Fish shell. #+NAME: fish-extensions-gen #+BEGIN_SRC emacs-lisp :var extensions=fish-extensions-table[,0] - (mapconcat (lambda (x) (format "fisher add %s" x)) - extensions - "\n") +(mapconcat (lambda (x) (format "fisher add %s" x)) + extensions + "\n") #+END_SRC #+RESULTS[a88b321ba9148acc8c28c7fb1aaf924c23b6b072]: fish-extensions-gen @@ -786,6 +790,6 @@ I generally use the following extensions in my Fish shell. : fisher add oh-my-fish/theme-bobthefish #+BEGIN_SRC fish :noweb yes - printf "\n# Installing Fisher Extensions ################################################\n\n" - <> +printf "\n# Installing Fisher Extensions ################################################\n\n" +<> #+END_SRC diff --git a/org/config/emacs.org b/org/config/emacs.org index 7642bd7..8f03ca2 100644 --- a/org/config/emacs.org +++ b/org/config/emacs.org @@ -42,16 +42,16 @@ as possible some built-in features of Emacs before they can be even loaded, speeding Emacs up a bit. #+headers: :exports code :results silent :lexical t #+begin_src emacs-lisp :mkdirp yes :tangle ~/.emacs.vanilla/early-init.el - (setq package-enable-at-startup nil - inhibit-startup-message t - frame-resize-pixelwise t ; fine resize - package-native-compile t) ; native compile packages - (scroll-bar-mode -1) ; disable scrollbar - (tool-bar-mode -1) ; disable toolbar - (tooltip-mode -1) ; disable tooltips - (set-fringe-mode 10) ; give some breathing room - (menu-bar-mode -1) ; disable menubar - (blink-cursor-mode 0) ; disable blinking cursor +(setq package-enable-at-startup nil + inhibit-startup-message t + frame-resize-pixelwise t ; fine resize + package-native-compile t) ; native compile packages +(scroll-bar-mode -1) ; disable scrollbar +(tool-bar-mode -1) ; disable toolbar +(tooltip-mode -1) ; disable tooltips +(set-fringe-mode 10) ; give some breathing room +(menu-bar-mode -1) ; disable menubar +(blink-cursor-mode 0) ; disable blinking cursor #+end_src ** Emacs Behavior @@ -65,13 +65,13 @@ loaded, speeding Emacs up a bit. I *never* want to keep trailing spaces in my files, which is why I’m doing this: #+begin_src emacs-lisp - (add-hook 'before-save-hook #'whitespace-cleanup) +(add-hook 'before-save-hook #'whitespace-cleanup) #+end_src I don’t understand why some people add two spaces behind a full stop, I sure don’t. Let’s tell Emacs. #+begin_src emacs-lisp - (setq-default sentence-end-double-space nil) +(setq-default sentence-end-double-space nil) #+end_src There is a minor mode in Emacs which allows to have a finer way of @@ -80,12 +80,12 @@ would usually be considered by Emacs a word can be understood as several modes, as in camelCase words, and allows us to jump words on this finer level. #+begin_src emacs-lisp - (global-subword-mode 1) +(global-subword-mode 1) #+end_src Lastly, I want the default mode for Emacs to be Emacs Lisp. #+begin_src emacs-lisp - (setq-default initial-major-mode 'emacs-lisp-mode) +(setq-default initial-major-mode 'emacs-lisp-mode) #+end_src **** Indentation @@ -97,8 +97,8 @@ almost always tell Emacs to use them through a ~.dir-locals.el~ file or through the config file of my code formatter. So by default, let’s disable them: #+begin_src emacs-lisp - (setq-default indent-tabs-mode nil) - (add-hook 'prog-mode-hook (lambda () (setq indent-tabs-mode nil))) +(setq-default indent-tabs-mode nil) +(add-hook 'prog-mode-hook (lambda () (setq indent-tabs-mode nil))) #+end_src Just to go on a little tangeant here: I don’t exactly /hate/ tabs, but I @@ -147,9 +147,9 @@ fit mine, so on top of ~prog-mode~, let’s add a few other modes. #+name: prog-modes-gen #+headers: :cache yes :exports none :tangle no #+begin_src emacs-lisp :var modes=line-number-modes-table - (mapconcat (lambda (mode) (format "%s-hook" (car mode))) - modes - " ") +(mapconcat (lambda (mode) (format "%s-hook" (car mode))) + modes + " ") #+end_src #+RESULTS[b551840c279e88374f47f047e599b8d8686fd8bf]: prog-modes-gen @@ -164,8 +164,8 @@ numbers on the left-side of the buffer. This is a fantastic feature that should actually be the default for all programming modes. #+begin_src emacs-lisp - (dolist (mode '(<>)) - (add-hook mode #'display-line-numbers-mode)) +(dolist (mode '(<>)) + (add-hook mode #'display-line-numbers-mode)) #+end_src **** Folding code @@ -177,8 +177,8 @@ code between curly braces, chunks of comments or code on another level of indentation (Python, why…?). The minor-mode that enables that is ~hs-minor-mode~, let’s enable it for all of these programming modes: #+begin_src emacs-lisp - (dolist (mode '(<>)) - (add-hook mode #'hs-minor-mode)) +(dolist (mode '(<>)) + (add-hook mode #'hs-minor-mode)) #+end_src *** Stay Clean, Emacs! @@ -201,20 +201,20 @@ there, but the thing is: I regenerate my ~init.el~ each time I tangle this file! How can I keep Emacs from adding stuff that will be almost immediately lost? Did someone say /custom file/? #+begin_src emacs-lisp - (setq-default custom-file (expand-file-name ".custom.el" user-emacs-directory)) - (when (file-exists-p custom-file) ; Don’t forget to load it, we still need it - (load custom-file)) +(setq-default custom-file (expand-file-name ".custom.el" user-emacs-directory)) +(when (file-exists-p custom-file) ; Don’t forget to load it, we still need it + (load custom-file)) #+end_src If we delete a file, we want it moved to the trash, not simply deleted. #+begin_src emacs-lisp - (setq delete-by-moving-to-trash t) +(setq delete-by-moving-to-trash t) #+end_src Finally, the scatch buffer always has some message at its beginning, I don’t want it! #+begin_src emacs-lisp - (setq-default initial-scratch-message nil) +(setq-default initial-scratch-message nil) #+end_src *** Stay Polite, Emacs! @@ -225,7 +225,7 @@ When asking for our opinion on something, Emacs loves asking us to answer by “yes” or “no”, but *in full*! That’s very rude! Fortunately, we can fix this. #+begin_src emacs-lisp - (defalias 'yes-or-no-p 'y-or-n-p) +(defalias 'yes-or-no-p 'y-or-n-p) #+end_src This will make Emacs ask us for either hitting the ~y~ key for “yes”, or @@ -234,7 +234,7 @@ the ~n~ key for “no”. Much more polite! It is also very impolite to keep a certain version of a file in its buffer when said file has changed on disk. Let’s change this behavior: #+begin_src emacs-lisp - (global-auto-revert-mode 1) +(global-auto-revert-mode 1) #+end_src #+RESULTS: @@ -251,12 +251,12 @@ your unsaved changes won’t be lost. Very polite! Let’s raise Emacs undo memory to 10MB, and make Emacs auto-save our files by default. #+begin_src emacs-lisp - (setq undo-limit 100000000 - auto-save-default t) +(setq undo-limit 100000000 + auto-save-default t) #+end_src #+begin_src emacs-lisp - (setq window-combination-resize t) ; take new window space from all other windows +(setq window-combination-resize t) ; take new window space from all other windows #+end_src ** Personal Information @@ -268,10 +268,10 @@ packages rely of these variables to know who it is talking to or dealing with, such as ~mu4e~ which will guess who you are if you haven’t set it up correctly. #+begin_src emacs-lisp - (setq user-full-name "Lucien Cartier-Tilet" - user-real-login-name "Lucien Cartier-Tilet" - user-login-name "phundrak" - user-mail-address "lucien@phundrak.com") +(setq user-full-name "Lucien Cartier-Tilet" + user-real-login-name "Lucien Cartier-Tilet" + user-login-name "phundrak" + user-mail-address "lucien@phundrak.com") #+end_src ** Visual Configuration @@ -283,18 +283,18 @@ bell. What it does is I get a visual feedback each time I do something Emacs doesn’t agree with, like tring to go up a line when I’m already at the top of the buffer. #+begin_src emacs-lisp - (setq visible-bell t) +(setq visible-bell t) #+end_src It is nicer to see a cursor cover the actual space of a character. #+begin_src emacs-lisp - (setq x-stretch-cursor t) +(setq x-stretch-cursor t) #+end_src When text is ellipsed, I want the ellipsis marker to be a single character of three dots. Let’s make it so: #+begin_src emacs-lisp - (setq truncate-string-ellipsis "…") +(setq truncate-string-ellipsis "…") #+end_src *** Modeline Modules @@ -306,24 +306,24 @@ hidden. This is why I want the current date and time to be displayed, in an ISO-8601 style, although not exactly ISO-8601 (this is the best time format, fight me). #+begin_src emacs-lisp - (setq display-time-format "%Y-%m-%d %H:%M") - (display-time-mode 1) ; display time in modeline +(setq display-time-format "%Y-%m-%d %H:%M") +(display-time-mode 1) ; display time in modeline #+end_src Something my taskbar doesn’t have is a battery indicator. However, I want it enabled only if I am on a laptop or if a battery is available. #+begin_src emacs-lisp - (let ((battery-str (battery))) - (unless (or (equal "Battery status not available" battery-str) - (string-match-p (regexp-quote "N/A") battery-str)) - (display-battery-mode 1))) +(let ((battery-str (battery))) + (unless (or (equal "Battery status not available" battery-str) + (string-match-p (regexp-quote "N/A") battery-str)) + (display-battery-mode 1))) #+end_src This isn’t a modeline module per se, but we have an indicator of the current line in Emacs. And although it is useful, I also often wish to know which column I’m on. This can be activated like so: #+begin_src emacs-lisp - (column-number-mode) +(column-number-mode) #+end_src The following code is, as will several chunks of code in this config, @@ -332,23 +332,23 @@ of the file if the file itself is a regular UTF-8 file with ~\n~ line ending. Be aware the ~doom-modeline-buffer-encoding~ variable is usabel here only because I use the Doom modeline as seen below. #+begin_src emacs-lisp - (defun modeline-contitional-buffer-encoding () - "Hide \"LF UTF-8\" in modeline. +(defun modeline-contitional-buffer-encoding () + "Hide \"LF UTF-8\" in modeline. - It is expected of files to be encoded with LF UTF-8, so only show - the encoding in the modeline if the encoding is worth notifying - the user." - (setq-local doom-modeline-buffer-encoding - (unless (and (memq (plist-get (coding-system-plist buffer-file-coding-system) :category) - '(coding-category-undecided coding-category-utf-8)) - (not (memq (coding-system-eol-type buffer-file-coding-system) '(1 2)))) - t))) +It is expected of files to be encoded with LF UTF-8, so only show +the encoding in the modeline if the encoding is worth notifying +the user." + (setq-local doom-modeline-buffer-encoding + (unless (and (memq (plist-get (coding-system-plist buffer-file-coding-system) :category) + '(coding-category-undecided coding-category-utf-8)) + (not (memq (coding-system-eol-type buffer-file-coding-system) '(1 2)))) + t))) #+end_src Now, let’s automate the call to this function in order to apply the modifications to the modeline each time we open a new file. #+begin_src emacs-lisp - (add-hook 'after-change-major-mode-hook #'modeline-contitional-buffer-encoding) +(add-hook 'after-change-major-mode-hook #'modeline-contitional-buffer-encoding) #+end_src *** Fonts @@ -358,11 +358,11 @@ modifications to the modeline each time we open a new file. I don’t like the default font I usually have on my machines, I really don’t. I prefer [[https://github.com/microsoft/cascadia-code][Cascadia Code]], as it also somewhat supports the [[https://www.internationalphoneticassociation.org/][IPA]]. #+begin_src emacs-lisp - (defvar phundrak/default-font-size 90 - "Default font size.") +(defvar phundrak/default-font-size 90 + "Default font size.") - (when (equal system-type 'gnu/linux) - (set-face-attribute 'default nil :font "Cascadia Code" :height phundrak/default-font-size)) +(when (equal system-type 'gnu/linux) + (set-face-attribute 'default nil :font "Cascadia Code" :height phundrak/default-font-size)) #+end_src *** Frame Title @@ -372,13 +372,13 @@ don’t. I prefer [[https://github.com/microsoft/cascadia-code][Cascadia Code]], This is straight-up copied from [[https://tecosaur.github.io/emacs-config/config.html#window-title][TEC]]’s configuration. See their comment on the matter. #+begin_src emacs-lisp - (setq frame-title-format - '("" - "%b" - (:eval - (let ((project-name (projectile-project-name))) - (unless (string= "-" project-name) - (format (if (buffer-modified-p) " ◉ %s" "  ●  %s") project-name)))))) +(setq frame-title-format + '("" + "%b" + (:eval + (let ((project-name (projectile-project-name))) + (unless (string= "-" project-name) + (format (if (buffer-modified-p) " ◉ %s" "  ●  %s") project-name)))))) #+end_src ** Nice Macros From Doom-Emacs @@ -389,51 +389,51 @@ Doom-Emacs has some really nice macros that can come in really handy, but since I prefer to rely on my own configuration, I’ll instead just copy their code here. First we get the ~after!~ macro: #+begin_src emacs-lisp - (require 'cl) - (defmacro after! (package &rest body) - "Evaluate BODY after PACKAGE have loaded. +(require 'cl) +(defmacro after! (package &rest body) + "Evaluate BODY after PACKAGE have loaded. - PACKAGE is a symbol or list of them. These are package names, not modes, - functions or variables. It can be: +PACKAGE is a symbol or list of them. These are package names, not modes, +functions or variables. It can be: - - An unquoted package symbol (the name of a package) - (after! helm BODY...) - - An unquoted list of package symbols (i.e. BODY is evaluated once both magit - and git-gutter have loaded) - (after! (magit git-gutter) BODY...) - - An unquoted, nested list of compound package lists, using any combination of - :or/:any and :and/:all - (after! (:or package-a package-b ...) BODY...) - (after! (:and package-a package-b ...) BODY...) - (after! (:and package-a (:or package-b package-c) ...) BODY...) - Without :or/:any/:and/:all, :and/:all are implied. +- An unquoted package symbol (the name of a package) + (after! helm BODY...) +- An unquoted list of package symbols (i.e. BODY is evaluated once both magit + and git-gutter have loaded) + (after! (magit git-gutter) BODY...) +- An unquoted, nested list of compound package lists, using any combination of + :or/:any and :and/:all + (after! (:or package-a package-b ...) BODY...) + (after! (:and package-a package-b ...) BODY...) + (after! (:and package-a (:or package-b package-c) ...) BODY...) + Without :or/:any/:and/:all, :and/:all are implied. - This is a wrapper around `eval-after-load' that: +This is a wrapper around `eval-after-load' that: - 1. Suppresses warnings for disabled packages at compile-time - 2. Supports compound package statements (see below) - 3. Prevents eager expansion pulling in autoloaded macros all at once" - (declare (indent defun) (debug t)) - (if (symbolp package) - (list (if (or (not (bound-and-true-p byte-compile-current-file)) - (require package nil 'noerror)) - #'progn - #'with-no-warnings) - ;; We intentionally avoid `with-eval-after-load' to prevent eager - ;; macro expansion from pulling (or failing to pull) in autoloaded - ;; macros/packages. - `(eval-after-load ',package ',(macroexp-progn body))) - (let ((p (car package))) - (cond ((not (keywordp p)) - `(after! (:and ,@package) ,@body)) - ((memq p '(:or :any)) - (macroexp-progn - (cl-loop for next in (cdr package) - collect `(after! ,next ,@body)))) - ((memq p '(:and :all)) - (dolist (next (cdr package)) - (setq body `((after! ,next ,@body)))) - (car body)))))) +1. Suppresses warnings for disabled packages at compile-time +2. Supports compound package statements (see below) +3. Prevents eager expansion pulling in autoloaded macros all at once" + (declare (indent defun) (debug t)) + (if (symbolp package) + (list (if (or (not (bound-and-true-p byte-compile-current-file)) + (require package nil 'noerror)) + #'progn + #'with-no-warnings) + ;; We intentionally avoid `with-eval-after-load' to prevent eager + ;; macro expansion from pulling (or failing to pull) in autoloaded + ;; macros/packages. + `(eval-after-load ',package ',(macroexp-progn body))) + (let ((p (car package))) + (cond ((not (keywordp p)) + `(after! (:and ,@package) ,@body)) + ((memq p '(:or :any)) + (macroexp-progn + (cl-loop for next in (cdr package) + collect `(after! ,next ,@body)))) + ((memq p '(:and :all)) + (dolist (next (cdr package)) + (setq body `((after! ,next ,@body)))) + (car body)))))) #+end_src * Custom Elisp @@ -451,17 +451,17 @@ copy their code here. First we get the ~after!~ macro: This function allows the user to open all marked files from a dired buffer as new Emacs buffers. #+begin_src emacs-lisp - (defun phundrak/open-marked-files (&optional files) - "Open all marked FILES in dired buffer as new Emacs buffers." - (interactive) - (let* ((file-list (if files - (list files) - (if (equal major-mode "dired-mode") - (dired-get-marked-files) - (list (buffer-file-name)))))) - (mapc (lambda (file-path) - (find-file file-path)) - (file-list)))) +(defun phundrak/open-marked-files (&optional files) + "Open all marked FILES in dired buffer as new Emacs buffers." + (interactive) + (let* ((file-list (if files + (list files) + (if (equal major-mode "dired-mode") + (dired-get-marked-files) + (list (buffer-file-name)))))) + (mapc (lambda (file-path) + (find-file file-path)) + (file-list)))) #+end_src *** ~xah/open-in-external-app~ @@ -469,23 +469,23 @@ buffer as new Emacs buffers. :CUSTOM_ID: Custom-Elisp-Dired-functions-xah-open-in-external-appnm6kel6184j0 :END: #+begin_src emacs-lisp - (defun xah/open-in-external-app (&optional file) - "Open FILE or dired marked FILE in external app. - The app is chosen from the user’s OS preference." - (interactive) - (let ((file-list (if file - (list file) - (if (equal major-mode "dired-mode") - (dired-get-marked-files) - (list (buffer-file-name))))) - (do-it-p (if (<= (length file-list) 5) - t - (y-or-n-p "Open more than 5 files? ")))) - (when do-it-p - (mapc (lambda (file-path) - (let ((process-connection-type nil)) - (start-process "" nil "xdg-open" file-path))) - file-list)))) +(defun xah/open-in-external-app (&optional file) + "Open FILE or dired marked FILE in external app. +The app is chosen from the user’s OS preference." + (interactive) + (let ((file-list (if file + (list file) + (if (equal major-mode "dired-mode") + (dired-get-marked-files) + (list (buffer-file-name))))) + (do-it-p (if (<= (length file-list) 5) + t + (y-or-n-p "Open more than 5 files? ")))) + (when do-it-p + (mapc (lambda (file-path) + (let ((process-connection-type nil)) + (start-process "" nil "xdg-open" file-path))) + file-list)))) #+end_src *** ~xah/dired-sort~ @@ -493,19 +493,19 @@ buffer as new Emacs buffers. :CUSTOM_ID: Custom-Elisp-Dired-functions-xah-dired-sort9fakel6184j0 :END: #+begin_src emacs-lisp - (defun xah/dired-sort () - "Sort dired dir listing in different ways. - Prompt for a choice." - (interactive) - (let (sort-by arg) - (setq sort-by (completing-read "Sort by:" '("name" "size" "date" "extension"))) - (pcase sort-by - ("name" (setq arg "-ahl --group-directories-first")) - ("date" (setq arg "-ahl -t --group-directories-first")) - ("size" (setq arg "-ahl -S --group-directories-first")) - ("extension" (setq arg "ahlD -X --group-directories-first")) - (otherwise (error "Dired-sort: unknown option %s" otherwise))) - (dired-sort-other arg))) +(defun xah/dired-sort () + "Sort dired dir listing in different ways. +Prompt for a choice." + (interactive) + (let (sort-by arg) + (setq sort-by (completing-read "Sort by:" '("name" "size" "date" "extension"))) + (pcase sort-by + ("name" (setq arg "-ahl --group-directories-first")) + ("date" (setq arg "-ahl -t --group-directories-first")) + ("size" (setq arg "-ahl -S --group-directories-first")) + ("extension" (setq arg "ahlD -X --group-directories-first")) + (otherwise (error "Dired-sort: unknown option %s" otherwise))) + (dired-sort-other arg))) #+end_src ** Switch between buffers @@ -516,15 +516,15 @@ Two default shortcuts I really like from Spacemacs are ~SPC b m~ and ~SPC b s~, which bring the user directly to the ~*Messages*~ buffer and the ~*scratch*~ buffer respectively. These functions do exactly this. #+begin_src emacs-lisp - (defun switch-to-messages-buffer () - "Switch to Messages buffer." - (interactive) - (switch-to-buffer "*Messages*")) +(defun switch-to-messages-buffer () + "Switch to Messages buffer." + (interactive) + (switch-to-buffer "*Messages*")) - (defun switch-to-scratch-buffer () - "Switch to Messages buffer." - (interactive) - (switch-to-buffer "*scratch*")) +(defun switch-to-scratch-buffer () + "Switch to Messages buffer." + (interactive) + (switch-to-buffer "*scratch*")) #+end_src ** Org Functions @@ -543,12 +543,12 @@ b s~, which bring the user directly to the ~*Messages*~ buffer and the | Code | ~~~ | 126 | #+begin_src emacs-lisp - (defun org-mode-emphasize-bold () - "Emphasize as bold the current region. +(defun org-mode-emphasize-bold () + "Emphasize as bold the current region. - See also `org-emphasize'." - (interactive) - (org-emphasize 42)) +See also `org-emphasize'." + (interactive) + (org-emphasize 42)) #+end_src *** Handle new windows @@ -559,21 +559,21 @@ The two functions below allow the user to not only create a new window to the right or below the current window (respectively), but also to focus the new window immediately. #+begin_src emacs-lisp - (defun split-window-right-and-focus () - (interactive) - (split-window-right) - (windmove-right) - (when (and (boundp 'golden-ratio-mode) - (symbol-value golden-ratio-mode)) - (golden-ratio))) +(defun split-window-right-and-focus () + (interactive) + (split-window-right) + (windmove-right) + (when (and (boundp 'golden-ratio-mode) + (symbol-value golden-ratio-mode)) + (golden-ratio))) - (defun split-window-below-and-focus () - (interactive) - (split-window-below) - (windmove-down) - (when (and (boundp 'golden-ratio-mode) - (symbol-value golden-ratio-mode)) - (golden-ratio))) +(defun split-window-below-and-focus () + (interactive) + (split-window-below) + (windmove-down) + (when (and (boundp 'golden-ratio-mode) + (symbol-value golden-ratio-mode)) + (golden-ratio))) #+end_src *** ~phundrak/toggle-org-src-window-split~ @@ -581,20 +581,20 @@ focus the new window immediately. :CUSTOM_ID: Custom-Elisp-Org-Functions-phundrak-toggle-org-src-window-splito2tkel6184j0 :END: #+begin_src emacs-lisp - (defun phundrak/toggle-org-src-window-split () - "This function allows the user to toggle the behavior of - `org-edit-src-code'. If the variable `org-src-window-setup' has - the value `split-window-right', then it will be changed to - `split-window-below'. Otherwise, it will be set back to - `split-window-right'" - (interactive) - (if (equal org-src-window-setup 'split-window-right) - (setq org-src-window-setup 'split-window-below) - (setq org-src-window-setup 'split-window-right)) - (message "Org-src buffers will now split %s" - (if (equal org-src-window-setup 'split-window-right) - "vertically" - "horizontally"))) +(defun phundrak/toggle-org-src-window-split () + "This function allows the user to toggle the behavior of +`org-edit-src-code'. If the variable `org-src-window-setup' has +the value `split-window-right', then it will be changed to +`split-window-below'. Otherwise, it will be set back to +`split-window-right'" + (interactive) + (if (equal org-src-window-setup 'split-window-right) + (setq org-src-window-setup 'split-window-below) + (setq org-src-window-setup 'split-window-right)) + (message "Org-src buffers will now split %s" + (if (equal org-src-window-setup 'split-window-right) + "vertically" + "horizontally"))) #+end_src * Package Management @@ -614,10 +614,10 @@ copyright assignment. Both the /gnu/ and the /nonfree/ repositories are Elpa repositories now, and they were renamed in order to avoid any confusion between the two of them. #+begin_src emacs-lisp - (setq package-archives '(("melpa" . "https://melpa.org/packages/") - ("org" . "https://orgmode.org/elpa/") - ("gnu" . "https://elpa.gnu.org/packages/") - ("nongnu" . "https://elpa.nongnu.org/nongnu/"))) +(setq package-archives '(("melpa" . "https://melpa.org/packages/") + ("org" . "https://orgmode.org/elpa/") + ("gnu" . "https://elpa.gnu.org/packages/") + ("nongnu" . "https://elpa.nongnu.org/nongnu/"))) #+end_src ** Straight @@ -631,30 +631,30 @@ but also because with it I can specify where to retrieve packages that are not on MELPA or ELPA but on Github and other online Git repositories too. #+begin_src emacs-lisp - (defvar bootstrap-version) - (defvar comp-deferred-compilation-deny-list ()) ; workaround, otherwise straight shits itself - (let ((bootstrap-file - (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory)) - (bootstrap-version 5)) - (unless (file-exists-p bootstrap-file) - (with-current-buffer - (url-retrieve-synchronously - "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el" - 'silent 'inhibit-cookies) - (goto-char (point-max)) - (eval-print-last-sexp))) - (load bootstrap-file nil 'nomessage)) +(defvar bootstrap-version) +(defvar comp-deferred-compilation-deny-list ()) ; workaround, otherwise straight shits itself +(let ((bootstrap-file + (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory)) + (bootstrap-version 5)) + (unless (file-exists-p bootstrap-file) + (with-current-buffer + (url-retrieve-synchronously + "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el" + 'silent 'inhibit-cookies) + (goto-char (point-max)) + (eval-print-last-sexp))) + (load bootstrap-file nil 'nomessage)) - (package-initialize) - (unless package-archive-contents - (package-refresh-contents)) +(package-initialize) +(unless package-archive-contents + (package-refresh-contents)) - ;; Initialize use-package on non-Linux platforms - (unless (package-installed-p 'use-package) - (package-install 'use-package)) +;; Initialize use-package on non-Linux platforms +(unless (package-installed-p 'use-package) + (package-install 'use-package)) - (require 'use-package) - (setq use-package-always-ensure t) +(require 'use-package) +(setq use-package-always-ensure t) #+end_src * Keybinding Management @@ -666,13 +666,13 @@ repositories too. :CUSTOM_ID: Keybinding-Management-Which-keymsblel6184j0 :END: #+begin_src emacs-lisp - (use-package which-key - :straight (:build t) - :defer t - :init (which-key-mode) - :diminish which-key-mode - :config - (setq which-key-idle-delay 1)) +(use-package which-key + :straight (:build t) + :defer t + :init (which-key-mode) + :diminish which-key-mode + :config + (setq which-key-idle-delay 1)) #+end_src ** General @@ -689,36 +689,36 @@ my keybinds that are not bound to a specific mode will be prefixed with ~SPC~, but when I want to get more specific in terms of mode, I'll prefix them with a comma (I’ve taken this habit from Spacemacs). #+begin_src emacs-lisp - (use-package general - :defer t - :straight (:build t) - :init - (general-auto-unbind-keys)) +(use-package general + :defer t + :straight (:build t) + :init + (general-auto-unbind-keys)) #+end_src #+name: general-keybindings-gen #+headers: :tangle no :exports none :results value :cache yes #+begin_src emacs-lisp :var table=mu4e-keybindings-view-tbl - (mapconcat (lambda (line) - (let* ((key (car line)) - (function (cadr line)) - (function (if (or (string= "nil" function) - (string= "" function)) - ":ignore" - function)) - (comment (caddr line))) - (format "\"%s\" %s" key - (if (string= "" comment) - (if (string= "nil" function) - "nil" - (concat "#'" function)) - (format "'(%s :which-key \"%s\")" - function - (if (string= "" function) - "nil" - comment)))))) - table - "\n") +(mapconcat (lambda (line) + (let* ((key (car line)) + (function (cadr line)) + (function (if (or (string= "nil" function) + (string= "" function)) + ":ignore" + function)) + (comment (caddr line))) + (format "\"%s\" %s" key + (if (string= "" comment) + (if (string= "nil" function) + "nil" + (concat "#'" function)) + (format "'(%s :which-key \"%s\")" + function + (if (string= "" function) + "nil" + comment)))))) + table + "\n") #+end_src #+RESULTS[fa2948b693499edc6458f60c46357955b8ace1fb]: general-keybindings-gen @@ -763,25 +763,25 @@ prefix them with a comma (I’ve taken this habit from Spacemacs). :CUSTOM_ID: Keybinding-Management-Eviljg30fl6184j0 :END: #+begin_src emacs-lisp - (use-package evil - :straight (:build t) - :init - (progn - (setq evil-want-integration t - evil-want-keybinding nil - evil-want-C-u-scroll t - evil-want-C-i-jump nil) - (require 'evil-vars) - (evil-set-undo-system 'undo-tree)) - :config - (evil-mode 1) - (setq evil-want-fine-undo t) ; more granular undo with evil - (evil-set-initial-state 'messages-buffer-mode 'normal) - (evil-set-initial-state 'dashboard-mode 'normal) +(use-package evil + :straight (:build t) + :init + (progn + (setq evil-want-integration t + evil-want-keybinding nil + evil-want-C-u-scroll t + evil-want-C-i-jump nil) + (require 'evil-vars) + (evil-set-undo-system 'undo-tree)) + :config + (evil-mode 1) + (setq evil-want-fine-undo t) ; more granular undo with evil + (evil-set-initial-state 'messages-buffer-mode 'normal) + (evil-set-initial-state 'dashboard-mode 'normal) - ;; Use visual line motions even outside of visual-line-mode buffers - (evil-global-set-key 'motion "t" 'evil-next-visual-line) - (evil-global-set-key 'motion "s" 'evil-previous-visual-line) + ;; Use visual line motions even outside of visual-line-mode buffers + (evil-global-set-key 'motion "t" 'evil-next-visual-line) + (evil-global-set-key 'motion "s" 'evil-previous-visual-line) (dolist (key '("c" "C" "t" "T" "s" "S" "r" "R" "h" "H" "j" "J" "k" "K" "l" "L")) (general-define-key :states 'normal key nil)) @@ -805,20 +805,22 @@ prefix them with a comma (I’ve taken this habit from Spacemacs). "S" 'evil-lookup "r" 'evil-forward-char "R" 'evil-window-bottom)) - - (use-package evil-collection - :after evil - :straight (:build t) - :config - (evil-collection-init)) #+end_src #+begin_src emacs-lisp - (use-package undo-tree - :defer t - :straight (:build t) - :init - (global-undo-tree-mode)) +(use-package evil-collection + :after evil + :straight (:build t) + :config + (evil-collection-init)) +#+end_src + +#+begin_src emacs-lisp +(use-package undo-tree + :defer t + :straight (:build t) + :init + (global-undo-tree-mode)) #+end_src ** Hydra @@ -827,9 +829,9 @@ prefix them with a comma (I’ve taken this habit from Spacemacs). :END: [[https://github.com/abo-abo/hydra][Hydra]] is a simple menu creator for keybindings. #+begin_src emacs-lisp - (use-package hydra - :straight (:build t) - :defer t) +(use-package hydra + :straight (:build t) + :defer t) #+end_src *** Hydras @@ -839,65 +841,65 @@ prefix them with a comma (I’ve taken this habit from Spacemacs). The following hydra allows me to quickly zoom in and out in the current buffer. #+begin_src emacs-lisp - (defhydra hydra-zoom () - " - ^Zoom^ ^Other - ^^^^^^^-------------------------- - [_t_/_s_] zoom in/out [_q_] quit - [_0_]^^ reset zoom +(defhydra hydra-zoom () " - ("t" text-scale-increase "zoom in") - ("s" text-scale-decrease "zoom out") - ("0" text-scale-adjust "reset") - ("q" nil "finished" :exit t)) +^Zoom^ ^Other +^^^^^^^-------------------------- +[_t_/_s_] zoom in/out [_q_] quit +[_0_]^^ reset zoom +" + ("t" text-scale-increase "zoom in") + ("s" text-scale-decrease "zoom out") + ("0" text-scale-adjust "reset") + ("q" nil "finished" :exit t)) #+end_src Similarly, this one is also inspired from Spacemacs and allows the user to interact with the width of the buffer in ~writeroom~. #+begin_src emacs-lisp - (defhydra writeroom-buffer-width () - " - ^Width^ ^Other - ^^^^^^^^----------------------- - [_t_] enlarge [_r_/_0_] adjust - [_s_] shrink [_q_]^^ quit +(defhydra writeroom-buffer-width () " - ("q" nil :exit t) - ("t" writeroom-increase-width "enlarge") - ("s" writeroom-decrease-width "shrink") - ("r" writeroom-adjust-width "adjust") - ("0" writeroom-adjust-width "adjust")) +^Width^ ^Other +^^^^^^^^----------------------- +[_t_] enlarge [_r_/_0_] adjust +[_s_] shrink [_q_]^^ quit +" + ("q" nil :exit t) + ("t" writeroom-increase-width "enlarge") + ("s" writeroom-decrease-width "shrink") + ("r" writeroom-adjust-width "adjust") + ("0" writeroom-adjust-width "adjust")) #+end_src Another similar one is for ~mu4e-view-mode~ that allows me to shrink or grow the ~mu4e-headers~ buffer when viewing an email. #+begin_src emacs-lisp - (defhydra mu4e-headers-split-adjust-width () - " - ^Zoom^ ^Other - ^^^^^^^--------------------------------- - [_t_/_s_] shrink/enlarge view [_q_] quit +(defhydra mu4e-headers-split-adjust-width () " - ("q" nil :exit t) - ("t" mu4e-headers-split-view-shrink "shrink") - ("s" mu4e-headers-split-view-grow "enlarge")) +^Zoom^ ^Other +^^^^^^^--------------------------------- +[_t_/_s_] shrink/enlarge view [_q_] quit +" + ("q" nil :exit t) + ("t" mu4e-headers-split-view-shrink "shrink") + ("s" mu4e-headers-split-view-grow "enlarge")) #+end_src Similarly still, this one allows me to manage the size my Emacs windows. #+begin_src emacs-lisp - (defhydra windows-adjust-size () - " - ^Zoom^ ^Other - ^^^^^^^----------------------------------------- - [_t_/_s_] shrink/enlarge vertically [_q_] quit - [_c_/_r_] shrink/enlarge horizontally +(defhydra windows-adjust-size () " - ("q" nil :exit t) - ("c" shrink-window-horizontally) - ("t" enlarge-window) - ("s" shrink-window) - ("r" enlarge-window-horizontally)) +^Zoom^ ^Other +^^^^^^^----------------------------------------- +[_t_/_s_] shrink/enlarge vertically [_q_] quit +[_c_/_r_] shrink/enlarge horizontally +" + ("q" nil :exit t) + ("c" shrink-window-horizontally) + ("t" enlarge-window) + ("s" shrink-window) + ("r" enlarge-window-horizontally)) #+end_src * Packages Configuration @@ -913,90 +915,94 @@ windows. :CUSTOM_ID: Packages-Configuration-Autocompletion-Code-Autocompletion4no1fl6184j0 :END: #+begin_src emacs-lisp - (use-package company - :straight (:build t) - :defer t - :hook (company-mode . evil-normalize-keymaps) - :init (global-company-mode) - :config - (setq company-minimum-prefix-length 2 - company-toolsip-limit 14 - company-tooltip-align-annotations t - company-require-match 'never - company-global-modes '(not erc-mode message-mode help-mode gud-mode) - company-frontends - '(company-pseudo-tooltip-frontend ; always show candidates in overlay tooltip - company-echo-metadata-frontend) ; show selected candidate docs in echo area +(use-package company + :straight (:build t) + :defer t + :hook (company-mode . evil-normalize-keymaps) + :init (global-company-mode) + :config + (setq company-minimum-prefix-length 2 + company-toolsip-limit 14 + company-tooltip-align-annotations t + company-require-match 'never + company-global-modes '(not erc-mode message-mode help-mode gud-mode) + company-frontends + '(company-pseudo-tooltip-frontend ; always show candidates in overlay tooltip + company-echo-metadata-frontend) ; show selected candidate docs in echo area - ;; Buffer-local backends will be computed when loading a major - ;; mode, so only specify a global default here. - company-backends '(company-capf) + ;; Buffer-local backends will be computed when loading a major + ;; mode, so only specify a global default here. + company-backends '(company-capf) - ;; These auto-complete the current selection when - ;; `company-auto-complete-chars' is typed. This is too - ;; magical. We already have the much more explicit RET and - ;; TAB. - company-auto-complete nil - company-auto-complete-chars nil + ;; These auto-complete the current selection when + ;; `company-auto-complete-chars' is typed. This is too + ;; magical. We already have the much more explicit RET and + ;; TAB. + company-auto-complete nil + company-auto-complete-chars nil - ;; Only search the current buffer for `company-dabbrev' (a - ;; backend that suggests text you open buffers). This prevents - ;; Company from causing lag once you have a lot of buffers - ;; open. - company-dabbrev-other-buffers nil + ;; Only search the current buffer for `company-dabbrev' (a + ;; backend that suggests text you open buffers). This prevents + ;; Company from causing lag once you have a lot of buffers + ;; open. + company-dabbrev-other-buffers nil - ;; Make `company-dabbrev' fully case-sensitive, to improve UX - ;; with domai-specific words with particular casing. - company-dabbrev-ignore-case nil - company-dabbrev-downcase nil)) + ;; Make `company-dabbrev' fully case-sensitive, to improve UX + ;; with domai-specific words with particular casing. + company-dabbrev-ignore-case nil + company-dabbrev-downcase nil)) +#+end_src - (use-package company-dict - :after company - :straight (:build t) - :config - (setq company-dict-dir (expand-file-name "dicts" user-emacs-directory))) +#+begin_src emacs-lisp +(use-package company-dict + :after company + :straight (:build t) + :config + (setq company-dict-dir (expand-file-name "dicts" user-emacs-directory))) +#+end_src - (use-package company-box - :straight (:build t) - :after (company all-the-icons) - :config - (setq company-box-show-single-candidate t - company-box-backends-colors nil - company-box-max-candidates 50 - company-box-icons-alist 'company-box-icons-all-the-icons - company-box-icons-all-the-icons - (let ((all-the-icons-scale-factor 0.8)) - `((Unknown . ,(all-the-icons-material "find_in_page" :face 'all-the-icons-purple)) - (Text . ,(all-the-icons-material "text_fields" :face 'all-the-icons-green)) - (Method . ,(all-the-icons-material "functions" :face 'all-the-icons-red)) - (Function . ,(all-the-icons-material "functions" :face 'all-the-icons-red)) - (Constructor . ,(all-the-icons-material "functions" :face 'all-the-icons-red)) - (Field . ,(all-the-icons-material "functions" :face 'all-the-icons-red)) - (Variable . ,(all-the-icons-material "adjust" :face 'all-the-icons-blue)) - (Class . ,(all-the-icons-material "class" :face 'all-the-icons-red)) - (Interface . ,(all-the-icons-material "settings_input_component" :face 'all-the-icons-red)) - (Module . ,(all-the-icons-material "view_module" :face 'all-the-icons-red)) - (Property . ,(all-the-icons-material "settings" :face 'all-the-icons-red)) - (Unit . ,(all-the-icons-material "straighten" :face 'all-the-icons-red)) - (Value . ,(all-the-icons-material "filter_1" :face 'all-the-icons-red)) - (Enum . ,(all-the-icons-material "plus_one" :face 'all-the-icons-red)) - (Keyword . ,(all-the-icons-material "filter_center_focus" :face 'all-the-icons-red)) - (Snippet . ,(all-the-icons-material "short_text" :face 'all-the-icons-red)) - (Color . ,(all-the-icons-material "color_lens" :face 'all-the-icons-red)) - (File . ,(all-the-icons-material "insert_drive_file" :face 'all-the-icons-red)) - (Reference . ,(all-the-icons-material "collections_bookmark" :face 'all-the-icons-red)) - (Folder . ,(all-the-icons-material "folder" :face 'all-the-icons-red)) - (EnumMember . ,(all-the-icons-material "people" :face 'all-the-icons-red)) - (Constant . ,(all-the-icons-material "pause_circle_filled" :face 'all-the-icons-red)) - (Struct . ,(all-the-icons-material "streetview" :face 'all-the-icons-red)) - (Event . ,(all-the-icons-material "event" :face 'all-the-icons-red)) - (Operator . ,(all-the-icons-material "control_point" :face 'all-the-icons-red)) - (TypeParameter . ,(all-the-icons-material "class" :face 'all-the-icons-red)) - (Template . ,(all-the-icons-material "short_text" :face 'all-the-icons-green)) - (ElispFunction . ,(all-the-icons-material "functions" :face 'all-the-icons-red)) - (ElispVariable . ,(all-the-icons-material "check_circle" :face 'all-the-icons-blue)) - (ElispFeature . ,(all-the-icons-material "stars" :face 'all-the-icons-orange)) - (ElispFace . ,(all-the-icons-material "format_paint" :face 'all-the-icons-pink)))))) +#+begin_src emacs-lisp +(use-package company-box + :straight (:build t) + :after (company all-the-icons) + :config + (setq company-box-show-single-candidate t + company-box-backends-colors nil + company-box-max-candidates 50 + company-box-icons-alist 'company-box-icons-all-the-icons + company-box-icons-all-the-icons + (let ((all-the-icons-scale-factor 0.8)) + `((Unknown . ,(all-the-icons-material "find_in_page" :face 'all-the-icons-purple)) + (Text . ,(all-the-icons-material "text_fields" :face 'all-the-icons-green)) + (Method . ,(all-the-icons-material "functions" :face 'all-the-icons-red)) + (Function . ,(all-the-icons-material "functions" :face 'all-the-icons-red)) + (Constructor . ,(all-the-icons-material "functions" :face 'all-the-icons-red)) + (Field . ,(all-the-icons-material "functions" :face 'all-the-icons-red)) + (Variable . ,(all-the-icons-material "adjust" :face 'all-the-icons-blue)) + (Class . ,(all-the-icons-material "class" :face 'all-the-icons-red)) + (Interface . ,(all-the-icons-material "settings_input_component" :face 'all-the-icons-red)) + (Module . ,(all-the-icons-material "view_module" :face 'all-the-icons-red)) + (Property . ,(all-the-icons-material "settings" :face 'all-the-icons-red)) + (Unit . ,(all-the-icons-material "straighten" :face 'all-the-icons-red)) + (Value . ,(all-the-icons-material "filter_1" :face 'all-the-icons-red)) + (Enum . ,(all-the-icons-material "plus_one" :face 'all-the-icons-red)) + (Keyword . ,(all-the-icons-material "filter_center_focus" :face 'all-the-icons-red)) + (Snippet . ,(all-the-icons-material "short_text" :face 'all-the-icons-red)) + (Color . ,(all-the-icons-material "color_lens" :face 'all-the-icons-red)) + (File . ,(all-the-icons-material "insert_drive_file" :face 'all-the-icons-red)) + (Reference . ,(all-the-icons-material "collections_bookmark" :face 'all-the-icons-red)) + (Folder . ,(all-the-icons-material "folder" :face 'all-the-icons-red)) + (EnumMember . ,(all-the-icons-material "people" :face 'all-the-icons-red)) + (Constant . ,(all-the-icons-material "pause_circle_filled" :face 'all-the-icons-red)) + (Struct . ,(all-the-icons-material "streetview" :face 'all-the-icons-red)) + (Event . ,(all-the-icons-material "event" :face 'all-the-icons-red)) + (Operator . ,(all-the-icons-material "control_point" :face 'all-the-icons-red)) + (TypeParameter . ,(all-the-icons-material "class" :face 'all-the-icons-red)) + (Template . ,(all-the-icons-material "short_text" :face 'all-the-icons-green)) + (ElispFunction . ,(all-the-icons-material "functions" :face 'all-the-icons-red)) + (ElispVariable . ,(all-the-icons-material "check_circle" :face 'all-the-icons-blue)) + (ElispFeature . ,(all-the-icons-material "stars" :face 'all-the-icons-orange)) + (ElispFace . ,(all-the-icons-material "format_paint" :face 'all-the-icons-pink)))))) #+end_src *** Ivy @@ -1009,80 +1015,80 @@ the latter as much as possible. Actually, only ~ivy~ is installed for now. I could have used ~ido~ too, but I find it to be a bit too restricted in terms of features compared to ~ivy~. #+begin_src emacs-lisp - (use-package ivy - :straight (:build t) - :defer t - :diminish - :bind (("C-s" . swiper) - :map ivy-minibuffer-map - ("TAB" . ivy-alt-done) - ("C-l" . ivy-alt-done) - ("C-t" . ivy-next-line) - ("C-s" . ivy-previous-line) - :map ivy-switch-buffer-map - ("C-t" . ivy-next-line) - ("C-s" . ivy-previous-line) - ("C-l" . ivy-done) - ("C-d" . ivy-switch-buffer-kill) - :map ivy-reverse-i-search-map - ("C-t" . ivy-next-line) - ("C-s" . ivy-previous-line) - ("C-d" . ivy-reverse-i-search-kill)) - :config - (ivy-mode 1) - (setq ivy-wrap t - ivy-height 17 - ivy-sort-max-size 50000 - ivy-fixed-height-minibuffer t - ivy-read-action-functions #'ivy-hydra-read-action - ivy-read-action-format-function #'ivy-read-action-format-columns - projectile-completion-system 'ivy - ivy-on-del-error-function #'ignore - ivy-use-selectable-prompt t)) +(use-package ivy + :straight (:build t) + :defer t + :diminish + :bind (("C-s" . swiper) + :map ivy-minibuffer-map + ("TAB" . ivy-alt-done) + ("C-l" . ivy-alt-done) + ("C-t" . ivy-next-line) + ("C-s" . ivy-previous-line) + :map ivy-switch-buffer-map + ("C-t" . ivy-next-line) + ("C-s" . ivy-previous-line) + ("C-l" . ivy-done) + ("C-d" . ivy-switch-buffer-kill) + :map ivy-reverse-i-search-map + ("C-t" . ivy-next-line) + ("C-s" . ivy-previous-line) + ("C-d" . ivy-reverse-i-search-kill)) + :config + (ivy-mode 1) + (setq ivy-wrap t + ivy-height 17 + ivy-sort-max-size 50000 + ivy-fixed-height-minibuffer t + ivy-read-action-functions #'ivy-hydra-read-action + ivy-read-action-format-function #'ivy-read-action-format-columns + projectile-completion-system 'ivy + ivy-on-del-error-function #'ignore + ivy-use-selectable-prompt t)) #+end_src There is also [[https://github.com/raxod502/prescient.el][~prescient.el~]] that offers some nice features when coupled with ~ivy~, guess what was born out of it? ~ivy-prescient~, of course! #+begin_src emacs-lisp - (use-package ivy-prescient - :after ivy - :straight (:build t)) +(use-package ivy-prescient + :after ivy + :straight (:build t)) #+end_src I warned you I’d use too much ~all-the-icons~, I did! #+begin_src emacs-lisp - (use-package all-the-icons-ivy - :straight (:build t) - :after (ivy all-the-icons) - :hook (after-init . all-the-icons-ivy-setup)) +(use-package all-the-icons-ivy + :straight (:build t) + :after (ivy all-the-icons) + :hook (after-init . all-the-icons-ivy-setup)) #+end_src A buffer popping at the bottom of the screen is nice and all, but have you considered a floating buffer in the center of your frame? #+begin_src emacs-lisp - (use-package ivy-posframe - :defer t - :after (:any ivy helpful) - :hook (ivy-mode . ivy-posframe-mode) - :straight (:build t) - :init - (ivy-posframe-mode 1) - :config - (setq ivy-fixed-height-minibuffer nil - ivy-posframe-border-width 10 - ivy-posframe-parameters - `((min-width . 90) - (min-height . ,ivy-height)))) +(use-package ivy-posframe + :defer t + :after (:any ivy helpful) + :hook (ivy-mode . ivy-posframe-mode) + :straight (:build t) + :init + (ivy-posframe-mode 1) + :config + (setq ivy-fixed-height-minibuffer nil + ivy-posframe-border-width 10 + ivy-posframe-parameters + `((min-width . 90) + (min-height . ,ivy-height)))) #+end_src Finally, let’s make ~ivy~ richer: #+begin_src emacs-lisp - (use-package ivy-rich - :straight (:build t) - :after ivy - :init - (ivy-rich-mode 1)) +(use-package ivy-rich + :straight (:build t) + :after ivy + :init + (ivy-rich-mode 1)) #+end_src *** Counsel @@ -1090,15 +1096,15 @@ Finally, let’s make ~ivy~ richer: :CUSTOM_ID: Packages-Configuration-Autocompletion-Counselorr1fl6184j0 :END: #+begin_src emacs-lisp - (use-package counsel - :straight (:build t) - :defer t - :after ivy - :bind (("M-x" . counsel-M-x) - ("C-x b" . counsel-ibuffer) - ("C-x C-f" . counsel-find-file) - :map minibuffer-local-map - ("C-r" . 'counsel-minibuffer-history))) +(use-package counsel + :straight (:build t) + :defer t + :after ivy + :bind (("M-x" . counsel-M-x) + ("C-x b" . counsel-ibuffer) + ("C-x C-f" . counsel-find-file) + :map minibuffer-local-map + ("C-r" . 'counsel-minibuffer-history))) #+end_src *** Yasnippet @@ -1106,34 +1112,34 @@ Finally, let’s make ~ivy~ richer: :CUSTOM_ID: Packages-Configuration-Autocompletion-Yasnippet68t1fl6184j0 :END: #+begin_src emacs-lisp - (use-package yasnippet - :defer t - :straight (:build t) - :init - (yas-global-mode) - :hook ((prog-mode . yas-minor-mode) - (text-mode . yas-minor-mode))) +(use-package yasnippet + :defer t + :straight (:build t) + :init + (yas-global-mode) + :hook ((prog-mode . yas-minor-mode) + (text-mode . yas-minor-mode))) #+end_src #+begin_src emacs-lisp - (use-package yasnippet-snippets - :defer t - :after yasnippet - :straight (:build t)) +(use-package yasnippet-snippets + :defer t + :after yasnippet + :straight (:build t)) #+end_src #+begin_src emacs-lisp - (use-package yatemplate - :defer t - :after yasnippet - :straight (:build t)) +(use-package yatemplate + :defer t + :after yasnippet + :straight (:build t)) #+end_src #+begin_src emacs-lisp - (use-package ivy-yasnippet - :defer t - :after (ivy yasnippet) - :straight (:build t)) +(use-package ivy-yasnippet + :defer t + :after (ivy yasnippet) + :straight (:build t)) #+end_src ** Applications @@ -1147,12 +1153,12 @@ Finally, let’s make ~ivy~ richer: Docker is an awesome tool for reproducible development environments. Due to this, I absolutely need a mode for editing Dockerfiles. #+begin_src emacs-lisp - (use-package dockerfile-mode - :defer t - :straight (:build t) - :init - (put 'docker-image-name 'safe-local-variable #'stringp) - :mode "Dockerfile\\'") +(use-package dockerfile-mode + :defer t + :straight (:build t) + :init + (put 'docker-image-name 'safe-local-variable #'stringp) + :mode "Dockerfile\\'") #+end_src The =docker= package also provides interactivity with Docker and @@ -1180,8 +1186,8 @@ default my signature. Therefore, there is no need for Emacs itself to know about it since I don’t want it to include it a second time after ~org-msg~ already did. #+begin_src emacs-lisp - (setq message-signature nil - mail-signature nil) +(setq message-signature nil + mail-signature nil) #+end_src **** Mu4e @@ -1199,84 +1205,84 @@ configuration for the ~mu4e~ package itself. Quick sidenote: on ArchLinux, you’ll need to install either ~mu~ or ~mu-git~ from the AUR in order to use mu4e. #+begin_src emacs-lisp - (use-package mu4e - :after all-the-icons - :straight (:build t :location site) - :commands mu4e mu4e-compose-new - :init - (progn - (setq mu4e-completing-read-function 'completing-read - mu4e-use-fancy-chars t - mu4e-view-show-images t - message-kill-buffer-on-exit t - mu4e-org-support nil) - (let ((dir "~/Downloads/mu4e")) - (when (file-directory-p dir) - (setq mu4e-attachment-dir dir)))) +(use-package mu4e + :after all-the-icons + :straight (:build t :location site) + :commands mu4e mu4e-compose-new + :init + (progn + (setq mu4e-completing-read-function 'completing-read + mu4e-use-fancy-chars t + mu4e-view-show-images t + message-kill-buffer-on-exit t + mu4e-org-support nil) + (let ((dir "~/Downloads/mu4e")) + (when (file-directory-p dir) + (setq mu4e-attachment-dir dir)))) - :config - <> - <> - <> + :config + <> + <> + <> - <> + <> - ;; Keybindings - <> - <> - <> - <> - <> + ;; Keybindings + <> + <> + <> + <> + <> - (when (fboundp 'imagemagick-register-types) - (imagemagick-register-types)) + (when (fboundp 'imagemagick-register-types) + (imagemagick-register-types)) - (add-to-list 'mu4e-view-actions '("View in browser" . mu4e-action-view-in-browser) t) - (add-to-list 'mu4e-view-actions '("PDF view" . mu4e-action-open-as-pdf) t) + (add-to-list 'mu4e-view-actions '("View in browser" . mu4e-action-view-in-browser) t) + (add-to-list 'mu4e-view-actions '("PDF view" . mu4e-action-open-as-pdf) t) - (require 'gnus-dired) - (setq gnus-dired-mail-mode 'mu4e-user-agent) + (require 'gnus-dired) + (setq gnus-dired-mail-mode 'mu4e-user-agent) - (add-hook 'mu4e-compose-mode-hook (lambda () (use-hard-newlines t 'guess))) - (add-hook 'mu4e-compose-mode-hook 'mml-secure-message-sign-pgpmime) + (add-hook 'mu4e-compose-mode-hook (lambda () (use-hard-newlines t 'guess))) + (add-hook 'mu4e-compose-mode-hook 'mml-secure-message-sign-pgpmime) - (setq mu4e-change-filenames-when-moving t - mu4e-update-interval 60 - mu4e-compose-format-flowed t - mu4e-view-show-addresses t - mu4e-sent-messages-behaviour 'sent - mu4e-hide-index-messages t - mu4e-view-show-images t ; try to show images - mu4e-view-image-max-width 600 - message-send-mail-function #'smtpmail-send-it ; how to send an email - smtpmail-stream-type 'starttls - message-kill-buffer-on-exit t ; close after sending - mu4e-context-policy 'pick-first ; start with first (default) context - mu4e-compose-context-policy 'ask-if-none ; compose with current context, or ask - mu4e-completing-read-function #'ivy-completing-read ; use ivy - mu4e-confirm-quit t ; no need to ask - mu4e-header-fields '((:account . 12) - (:human-date . 12) - (:flags . 4) - (:from . 25) - (:subject))) + (setq mu4e-change-filenames-when-moving t + mu4e-update-interval 60 + mu4e-compose-format-flowed t + mu4e-view-show-addresses t + mu4e-sent-messages-behaviour 'sent + mu4e-hide-index-messages t + mu4e-view-show-images t ; try to show images + mu4e-view-image-max-width 600 + message-send-mail-function #'smtpmail-send-it ; how to send an email + smtpmail-stream-type 'starttls + message-kill-buffer-on-exit t ; close after sending + mu4e-context-policy 'pick-first ; start with first (default) context + mu4e-compose-context-policy 'ask-if-none ; compose with current context, or ask + mu4e-completing-read-function #'ivy-completing-read ; use ivy + mu4e-confirm-quit t ; no need to ask + mu4e-header-fields '((:account . 12) + (:human-date . 12) + (:flags . 4) + (:from . 25) + (:subject))) - ;; set mail user agent - (setq mail-user-agent 'mu4e-user-agent) + ;; set mail user agent + (setq mail-user-agent 'mu4e-user-agent) - <> - <> - <> + <> + <> + <> - (defun mu4e-action-open-as-pdf (msg) - "Export and open MSG as pdf." - (let* ((date (mu4e-message-field msg :date)) - (infile (mu4e~write-body-to-html msg)) - (outfile (format-time-string "/tmp/%Y-%m-%d-%H-%M-%S.pdf" date))) - (with-temp-buffer - (shell-command - (format "wkhtmltopdf %s %s" infile outfile) t)) - (find-file outfile)))) + (defun mu4e-action-open-as-pdf (msg) + "Export and open MSG as pdf." + (let* ((date (mu4e-message-field msg :date)) + (infile (mu4e~write-body-to-html msg)) + (outfile (format-time-string "/tmp/%Y-%m-%d-%H-%M-%S.pdf" date))) + (with-temp-buffer + (shell-command + (format "wkhtmltopdf %s %s" infile outfile) t)) + (find-file outfile)))) #+end_src ***** Basic configuration @@ -1287,29 +1293,29 @@ First, let’s inform Emacs how it can send emails, using which service and how. In my case, I use my own mail server. #+name: mu4e-mail-service #+begin_src emacs-lisp :tangle no - (setq smtpmail-smtp-server "mail.phundrak.com" - smtpmail-smtp-service 587 - smtpmail-stream-type 'starttls - message-send-mail-function 'smtpmail-send-it) +(setq smtpmail-smtp-server "mail.phundrak.com" + smtpmail-smtp-service 587 + smtpmail-stream-type 'starttls + message-send-mail-function 'smtpmail-send-it) #+end_src We also need to inform it on where my emails are stored on my machine, and how to retrieve them. #+name: mu4e-mail-on-machine #+begin_src emacs-lisp :tangle no - (setq mu4e-get-mail-command "mbsync -a" - mu4e-maildir "~/Mail" - mu4e-trash-folder "/Trash" - mu4e-refile-folder "/Archive" - mu4e-sent-folder "/Sent" - mu4e-drafts-folder "/Drafts") +(setq mu4e-get-mail-command "mbsync -a" + mu4e-maildir "~/Mail" + mu4e-trash-folder "/Trash" + mu4e-refile-folder "/Archive" + mu4e-sent-folder "/Sent" + mu4e-drafts-folder "/Drafts") #+end_src In the same vein of [[*Basic configuration][this bit of configuration]], I do not want mu4e to insert my mail signature, ~org-msg~ already does that. #+name: mu4e-no-signature #+begin_src emacs-lisp :tangle no - (setq mu4e-compose-signature nil) +(setq mu4e-compose-signature nil) #+end_src ***** Actions on messages @@ -1343,10 +1349,10 @@ Paris 8 (my university). #+name: mu4e-bookmarks-filter-uni #+headers: :tangle no :cache yes #+begin_src emacs-lisp - (string-join '("f:/.*up8\.edu|.*univ-paris8.*/" - "c:/.*up8\.edu|.*univ-paris8.*/" - "t:/.*up8\.edu|.*univ-paris8.*/") - " OR ") +(string-join '("f:/.*up8\.edu|.*univ-paris8.*/" + "c:/.*up8\.edu|.*univ-paris8.*/" + "t:/.*up8\.edu|.*univ-paris8.*/") + " OR ") #+end_src #+RESULTS[6f0c2005657e701b0a992061981317febcdd6200]: mu4e-bookmarks-filter-uni @@ -1357,13 +1363,13 @@ mailing list address but also its old address. #+name: mu4e-bookmarks-filter-emacs-list #+headers: :tangle no :cache yes #+begin_src emacs-lisp - (mapconcat (lambda (address) - (mapconcat (lambda (flag) - (concat flag ":" address)) - '("list" "to" "from") - " OR ")) - '("ateliers-emacs.framalistes.org" "ateliers-paris.emacs-doctor.com") - " OR ") +(mapconcat (lambda (address) + (mapconcat (lambda (flag) + (concat flag ":" address)) + '("list" "to" "from") + " OR ")) + '("ateliers-emacs.framalistes.org" "ateliers-paris.emacs-doctor.com") + " OR ") #+end_src #+RESULTS[cff1b5e400cca47c06057bf236d099db01411cd7]: mu4e-bookmarks-filter-emacs-list @@ -1375,13 +1381,13 @@ subscribed anymore, but it’ll keep my inbox clean. #+name: mu4e-bookmarks-filter-conlang-list #+headers: :tangle no :cache yes #+begin_src emacs-lisp - (mapconcat (lambda (address) - (mapconcat (lambda (flag) - (concat flag ":" address)) - '("from" "to" "list") - " OR ")) - '("CONLANG@LISTSERV.BROWN.EDU" "AUXLANG@LISTSERV.BROWN.EDU") - " OR ") +(mapconcat (lambda (address) + (mapconcat (lambda (flag) + (concat flag ":" address)) + '("from" "to" "list") + " OR ")) + '("CONLANG@LISTSERV.BROWN.EDU" "AUXLANG@LISTSERV.BROWN.EDU") + " OR ") #+end_src #+RESULTS[129026cfdaeb910562b800b659ad8d2d13773932]: mu4e-bookmarks-filter-conlang-list @@ -1393,11 +1399,11 @@ junk emails, so I end up with the following rule: #+name: mu4e-bookmarks-default-filter #+headers: :tangle no :cache yes #+begin_src emacs-lisp - (string-join `("NOT flag:trashed" - ,(format "(%s)" (mapconcat (lambda (maildir) (concat "maildir:" maildir)) - '("/Inbox" "/Junk") - " OR "))) - " AND ") +(string-join `("NOT flag:trashed" + ,(format "(%s)" (mapconcat (lambda (maildir) (concat "maildir:" maildir)) + '("/Inbox" "/Junk") + " OR "))) + " AND ") #+end_src #+RESULTS[ccf162e159f77ccf87ff4fae220106f0a91ad256]: mu4e-bookmarks-default-filter @@ -1407,16 +1413,16 @@ And for the last string-generating code, let’s describe my main inbox: #+name: mu4e-bookmarks-inbox-filters #+headers: :tangle no :cache yes #+begin_src emacs-lisp - (string-join (cons - <> - `( - ,(format "(%s)" - <>) - ,(format "(%s)" - <>) - ,(format "(%s)" - <>))) - " AND NOT ") +(string-join (cons + <> + `( + ,(format "(%s)" + <>) + ,(format "(%s)" + <>) + ,(format "(%s)" + <>))) + " AND NOT ") #+end_src #+RESULTS[2bd917f15a55a2a509f5710c6a4db5f8a8e7a596]: mu4e-bookmarks-inbox-filters @@ -1425,40 +1431,40 @@ And for the last string-generating code, let’s describe my main inbox: We can finally define our bookmarks! The code reads as follows: #+name: mu4e-bookmarks #+begin_src emacs-lisp :tangle no :cache yes - (setq mu4e-bookmarks - `((:name "Inbox" - :key ?i - :query ,(format "%s" - <>)) - (:name "Linguistics" - :key ?l - :query ,(format "%s AND %s" - <> - <>)) - (:name "Emacs" - :key ?e - :query ,(format "%s AND %s" - <> - <>)) - (:name "University" - :key ?u - :query ,(format "%s AND %s" - <> - <>)) - (:name "eshell-info-banner" - :key ?E - :query ,(format "%s AND %s" - <> - "list:eshell-info-banner.el.Phundrak.github.com")) - (:name "Sent" :key ?s :query "maildir:/Sent") - (:name "All Unread" :key ?U :query "flag:unread AND NOT flag:trashed") - (:name "Today" :key ?t :query "date:today..now AND NOT flag:trashed") - (:name "This Week" :key ?w :query "date:7d..now AND NOT flag:trashed") - (:name "This Month" :key ?m :query "date:1m..now AND NOT flag:trashed") - (:name "This Year" :key ?y :query "date:1y..now AND NOT flag:trashed"))) +(setq mu4e-bookmarks + `((:name "Inbox" + :key ?i + :query ,(format "%s" + <>)) + (:name "Linguistics" + :key ?l + :query ,(format "%s AND %s" + <> + <>)) + (:name "Emacs" + :key ?e + :query ,(format "%s AND %s" + <> + <>)) + (:name "University" + :key ?u + :query ,(format "%s AND %s" + <> + <>)) + (:name "eshell-info-banner" + :key ?E + :query ,(format "%s AND %s" + <> + "list:eshell-info-banner.el.Phundrak.github.com")) + (:name "Sent" :key ?s :query "maildir:/Sent") + (:name "All Unread" :key ?U :query "flag:unread AND NOT flag:trashed") + (:name "Today" :key ?t :query "date:today..now AND NOT flag:trashed") + (:name "This Week" :key ?w :query "date:7d..now AND NOT flag:trashed") + (:name "This Month" :key ?m :query "date:1m..now AND NOT flag:trashed") + (:name "This Year" :key ?y :query "date:1y..now AND NOT flag:trashed"))) #+end_src -#+RESULTS[4a18e1cfa32f399203b300f7cbd986a553a1b234]: mu4e-bookmarks +#+RESULTS[b3dc7eb1936a879ab07bb2c5acdfb05cf330285a]: mu4e-bookmarks | :name | Inbox | :key | 105 | :query | NOT flag:trashed AND (maildir:/Inbox OR maildir:/Junk) AND NOT (from:CONLANG@LISTSERV.BROWN.EDU OR to:CONLANG@LISTSERV.BROWN.EDU OR list:CONLANG@LISTSERV.BROWN.EDU OR from:AUXLANG@LISTSERV.BROWN.EDU OR to:AUXLANG@LISTSERV.BROWN.EDU OR list:AUXLANG@LISTSERV.BROWN.EDU) AND NOT (list:ateliers-emacs.framalistes.org OR to:ateliers-emacs.framalistes.org OR from:ateliers-emacs.framalistes.org OR list:ateliers-paris.emacs-doctor.com OR to:ateliers-paris.emacs-doctor.com OR from:ateliers-paris.emacs-doctor.com) AND NOT (f:/.*up8.edu | .*univ-paris8.*/ OR c:/.*up8.edu | .*univ-paris8.*/ OR t:/.*up8.edu | .*univ-paris8.*/) | | | | | :name | Linguistics | :key | 108 | :query | NOT flag:trashed AND (maildir:/Inbox OR maildir:/Junk) AND NOT (from:CONLANG@LISTSERV.BROWN.EDU OR to:CONLANG@LISTSERV.BROWN.EDU OR list:CONLANG@LISTSERV.BROWN.EDU OR from:AUXLANG@LISTSERV.BROWN.EDU OR to:AUXLANG@LISTSERV.BROWN.EDU OR list:AUXLANG@LISTSERV.BROWN.EDU) AND NOT (list:ateliers-emacs.framalistes.org OR to:ateliers-emacs.framalistes.org OR from:ateliers-emacs.framalistes.org OR list:ateliers-paris.emacs-doctor.com OR to:ateliers-paris.emacs-doctor.com OR from:ateliers-paris.emacs-doctor.com) AND NOT (f:/.*up8.edu | .*univ-paris8.*/ OR c:/.*up8.edu | .*univ-paris8.*/ OR t:/.*up8.edu | .*univ-paris8.*/) AND from:CONLANG@LISTSERV.BROWN.EDU OR to:CONLANG@LISTSERV.BROWN.EDU OR list:CONLANG@LISTSERV.BROWN.EDU OR from:AUXLANG@LISTSERV.BROWN.EDU OR to:AUXLANG@LISTSERV.BROWN.EDU OR list:AUXLANG@LISTSERV.BROWN.EDU | | | | | :name | Emacs | :key | 101 | :query | NOT flag:trashed AND (maildir:/Inbox OR maildir:/Junk) AND NOT (from:CONLANG@LISTSERV.BROWN.EDU OR to:CONLANG@LISTSERV.BROWN.EDU OR list:CONLANG@LISTSERV.BROWN.EDU OR from:AUXLANG@LISTSERV.BROWN.EDU OR to:AUXLANG@LISTSERV.BROWN.EDU OR list:AUXLANG@LISTSERV.BROWN.EDU) AND NOT (list:ateliers-emacs.framalistes.org OR to:ateliers-emacs.framalistes.org OR from:ateliers-emacs.framalistes.org OR list:ateliers-paris.emacs-doctor.com OR to:ateliers-paris.emacs-doctor.com OR from:ateliers-paris.emacs-doctor.com) AND NOT (f:/.*up8.edu | .*univ-paris8.*/ OR c:/.*up8.edu | .*univ-paris8.*/ OR t:/.*up8.edu | .*univ-paris8.*/) AND list:ateliers-emacs.framalistes.org OR to:ateliers-emacs.framalistes.org OR from:ateliers-emacs.framalistes.org OR list:ateliers-paris.emacs-doctor.com OR to:ateliers-paris.emacs-doctor.com OR from:ateliers-paris.emacs-doctor.com | | | | @@ -1482,15 +1488,15 @@ hero]]! Now, let me write a function that will insert their pre-written text at point so I don’t have to go back to their Twitter thread each time I want to shut spammers up. #+begin_src emacs-lisp - (defun reply-to-bill () - (interactive) - (insert "Please forward this email to bill@noprocurement.com, - and delete my email, as I’ll be changing jobs soon, and this - email address will no longer be active. +(defun reply-to-bill () + (interactive) + (insert "Please forward this email to bill@noprocurement.com, +and delete my email, as I’ll be changing jobs soon, and this +email address will no longer be active. - Bill Whiskoney is a senior partner at Nordic Procurement - Services, and he handles our budget and will help you further or - introduce you to someone who can.")) +Bill Whiskoney is a senior partner at Nordic Procurement +Services, and he handles our budget and will help you further or +introduce you to someone who can.")) #+end_src If you want the full story, make sure to read the whole thread, I @@ -1522,16 +1528,16 @@ redefine them as follows. Be aware the name of these icons are from #+name: mu4e-fancy-marks-gen #+header: :tangle no :exports none :results value :cache yes #+begin_src emacs-lisp :var table=mu4e-fancy-marks-tbl - (mapconcat (lambda (line) - (let ((mark (car line)) - (flag (cadr line)) - (icon (caddr line))) - (format "mu4e-headers-%s-mark `(\"%s\" . ,(all-the-icons-faicon \"%s\" :height 0.8))" - mark - flag - icon))) - table - "\n") +(mapconcat (lambda (line) + (let ((mark (car line)) + (flag (cadr line)) + (icon (caddr line))) + (format "mu4e-headers-%s-mark `(\"%s\" . ,(all-the-icons-faicon \"%s\" :height 0.8))" + mark + flag + icon))) + table + "\n") #+end_src #+RESULTS[c6ed5d4bec4c10339a7de52a70822af74d782e62]: mu4e-fancy-marks-gen @@ -1552,26 +1558,26 @@ mu4e-headers-signed-mark `("s" . ,(all-the-icons-faicon "certificate" :height 0. Let’s enable them and set them: #+name: mu4e-fancy-marks #+begin_src emacs-lisp :tangle no - (setq mu4e-use-fancy-chars t - <>) +(setq mu4e-use-fancy-chars t + <>) #+end_src #+name: mu4e-vertical-split #+begin_src emacs-lisp - (defun my/set-mu4e-headers-width () - (let ((width (window-body-width)) - (threshold (+ 120 80))) - (setq mu4e-split-view (if (> width threshold) - 'vertical - 'horizontal)) - (message "Window width: %d\tthreshold: %d\nSplit: %S" - width - threshold - mu4e-split-view))) +(defun my/set-mu4e-headers-width () + (let ((width (window-body-width)) + (threshold (+ 120 80))) + (setq mu4e-split-view (if (> width threshold) + 'vertical + 'horizontal)) + (message "Window width: %d\tthreshold: %d\nSplit: %S" + width + threshold + mu4e-split-view))) - (setq mu4e-headers-visible-columns 120 - mu4e-headers-visible-lines 15) - (add-hook 'mu4e-headers-mode-hook #'my/set-mu4e-headers-width) +(setq mu4e-headers-visible-columns 120 + mu4e-headers-visible-lines 15) +(add-hook 'mu4e-headers-mode-hook #'my/set-mu4e-headers-width) #+end_src #+RESULTS: mu4e-vertical-split @@ -1583,8 +1589,8 @@ Let’s enable them and set them: :END: #+name: mu4e-headers-mode #+begin_src emacs-lisp :tangle no - (add-hook 'mu4e-headers-mode-hook (lambda () (visual-line-mode -1))) - (add-hook 'mu4e-headers-mode-hook (lambda () (toggle-truncate-lines -1))) +(add-hook 'mu4e-headers-mode-hook (lambda () (visual-line-mode -1))) +(add-hook 'mu4e-headers-mode-hook (lambda () (toggle-truncate-lines -1))) #+end_src ***** Keybindings @@ -1595,30 +1601,30 @@ By default, Evil has some pretty annoying keybindings for users of the bépo layout: ~hjkl~ becomes ~ctsr~ for us. Let’s undefine some of these: #+name: mu4e-keybindings-undef #+begin_src emacs-lisp :tangle no - (general-define-key - :keymaps '(mu4e-headers-mode-map mu4e-view-mode-map) - "SPC" nil - "s" nil) - (general-define-key - :states 'normal - :keymaps '(mu4e-headers-mode-map mu4e-view-mode-map) - "SPC" nil - "s" nil - "," nil) - (general-define-key - :keymaps 'mu4e-view-mode-map - "SPC" nil - "S" nil - "r" nil - "c" nil) - (general-define-key - :keymaps 'mu4e-view-mode-map - :states 'normal - "SPC" nil - "S" nil - "r" nil - "c" nil - "gu" nil) +(general-define-key + :keymaps '(mu4e-headers-mode-map mu4e-view-mode-map) + "SPC" nil + "s" nil) +(general-define-key + :states 'normal + :keymaps '(mu4e-headers-mode-map mu4e-view-mode-map) + "SPC" nil + "s" nil + "," nil) +(general-define-key + :keymaps 'mu4e-view-mode-map + "SPC" nil + "S" nil + "r" nil + "c" nil) +(general-define-key + :keymaps 'mu4e-view-mode-map + :states 'normal + "SPC" nil + "S" nil + "r" nil + "c" nil + "gu" nil) #+end_src Now, let’s define some keybindings for mu4e’s view mode, that is when @@ -1679,16 +1685,16 @@ one of the possible following key can act on a thread: #+name: mu4e-keybindings-view-lambdas-gen #+header: :tangle no :exports none :results value #+begin_src emacs-lisp :var table=mu4e-keybindings-view-lambdas-tbl mode="view" - (mapconcat (lambda (line) - (let ((key (car line)) - (mark (cadr line))) - (format "\"%s\" '((lambda () - (interactive) - (mu4e-%s-mark-thread '%s)) - :wk \"Mark as %s\")" - key mode mark mark))) - table - "\n") +(mapconcat (lambda (line) + (let ((key (car line)) + (mark (cadr line))) + (format "\"%s\" '((lambda () + (interactive) + (mu4e-%s-mark-thread '%s)) + :wk \"Mark as %s\")" + key mode mark mark))) + table + "\n") #+end_src #+RESULTS: mu4e-keybindings-view-lambdas-gen @@ -1725,12 +1731,12 @@ one of the possible following key can act on a thread: #+name: mu4e-keybindings-view #+begin_src emacs-lisp :tangle no - (general-define-key - :states 'normal - :keymaps 'mu4e-view-mode-map - :prefix "," - <> - <>) +(general-define-key + :states 'normal + :keymaps 'mu4e-view-mode-map + :prefix "," + <> + <>) #+end_src Some simple keybindings are defined for mu4e’s header mode: @@ -1745,12 +1751,12 @@ be reused for this mode. #+name: mu4e-keybindings-header #+begin_src emacs-lisp :tangle no - (general-define-key - :states 'normal - :keymaps 'mu4e-headers-mode-map - :prefix "," - <> - <>) +(general-define-key + :states 'normal + :keymaps 'mu4e-headers-mode-map + :prefix "," + <> + <>) #+end_src #+RESULTS: mu4e-keybindings-header @@ -1759,13 +1765,13 @@ I will also redefine without a leader key ~ctsr~ in order to be able to move freely (remember, bépo layout for me). #+name: mu4e-keybindings-header-no-leader #+begin_src emacs-lisp :tangle no - (general-define-key - :keymaps 'mu4e-headers-mode-map - :states 'normal - "c" #'evil-backward-char - "t" #'evil-next-line - "s" #'evil-previous-line - "r" #'evil-forward-char) +(general-define-key + :keymaps 'mu4e-headers-mode-map + :states 'normal + "c" #'evil-backward-char + "t" #'evil-next-line + "s" #'evil-previous-line + "r" #'evil-forward-char) #+end_src #+RESULTS: mu4e-keybindings-header-no-leader @@ -1785,11 +1791,11 @@ the major-mode leader and call a simple function. #+name: mu4e-keybindings-message #+begin_src emacs-lisp :tangle no - (general-define-key - :states 'normal - :keymaps 'message-mode-map - :prefix "," - <> +(general-define-key + :states 'normal + :keymaps 'message-mode-map + :prefix "," + <> #+end_src #+RESULTS: mu4e-keybindings-message @@ -1799,45 +1805,45 @@ the major-mode leader and call a simple function. :CUSTOM_ID: Packages-Configuration-Applications-Email-Composing-messagesth71fl6184j0 :END: #+begin_src emacs-lisp - (use-package org-msg - :after (org mu4e) - :straight (:build t) - :hook ((mu4e-compose-pre . org-msg-mode)) - :general (:keymaps 'org-msg-edit-mode-map - :prefix "," - :states 'normal - "," #'message-send-and-exit - "c" #'message-send-and-exit - "a" #'message-kill-buffer - "k" #'message-kill-buffer - "s" #'message-dont-send - "f" #'org-msg-attach) - :custom-face - (mu4e-replied-face ((t (:weight normal :foreground "#b48ead")))) - :config - (defun my/org-msg-signature-convert (orig-fun &rest args) - "Tweak my signature when replying as plain/text only." - (let ((res (apply orig-fun args))) - (when (equal (cadr args) '(text)) - (setf (alist-get 'signature res) - (replace-regexp-in-string "\n+" "\n" org-msg-signature))) - res)) - (advice-add 'org-msg-composition-parameters - :around 'my/org-msg-signature-convert) - (add-hook 'mu4e-headers-mode (lambda () (toggle-truncate-lines -1))) - (setq org-msg-startup "inlineimages" - org-msg-default-alternatives '((new . (text html)) - (reply-to-html . (text html)) - (reply-to-text . (text))) - org-msg-convert-citation t - org-msg-greeting-name-limit 3 - org-msg-signature (format "\n--\n#+begin_signature\n%s\n#+end_signature" +(use-package org-msg + :after (org mu4e) + :straight (:build t) + :hook ((mu4e-compose-pre . org-msg-mode)) + :general (:keymaps 'org-msg-edit-mode-map + :prefix "," + :states 'normal + "," #'message-send-and-exit + "c" #'message-send-and-exit + "a" #'message-kill-buffer + "k" #'message-kill-buffer + "s" #'message-dont-send + "f" #'org-msg-attach) + :custom-face + (mu4e-replied-face ((t (:weight normal :foreground "#b48ead")))) + :config + (defun my/org-msg-signature-convert (orig-fun &rest args) + "Tweak my signature when replying as plain/text only." + (let ((res (apply orig-fun args))) + (when (equal (cadr args) '(text)) + (setf (alist-get 'signature res) + (replace-regexp-in-string "\n+" "\n" org-msg-signature))) + res)) + (advice-add 'org-msg-composition-parameters + :around 'my/org-msg-signature-convert) + (add-hook 'mu4e-headers-mode (lambda () (toggle-truncate-lines -1))) + (setq org-msg-startup "inlineimages" + org-msg-default-alternatives '((new . (text html)) + (reply-to-html . (text html)) + (reply-to-text . (text))) + org-msg-convert-citation t + org-msg-greeting-name-limit 3 + org-msg-signature (format "\n--\n#+begin_signature\n%s\n#+end_signature" (string-trim (replace-regexp-in-string (regexp-quote "\n") "\n\n" - (with-temp-buffer - (insert-file-contents mail-signature-file) + (with-temp-buffer + (insert-file-contents mail-signature-file) (buffer-string))))))) #+end_src @@ -1850,15 +1856,15 @@ when new emails are received. By default, I want to be notified by all messages in my inbox and junk folder. Also, I’ll use Emacs’ default notification system, and I’ll activate the modeline notification. #+begin_src emacs-lisp - (use-package mu4e-alert - :straight (:build t) - :defer t - :init - (add-hook 'after-init-hook #'mu4e-alert-enable-notifications) - (add-hook 'after-init-hook #'mu4e-alert-enable-mode-line-display) - (mu4e-alert-set-default-style 'notifications) - :config - (setq mu4e-alert-interesting-mail-query "flag:unread")) +(use-package mu4e-alert + :straight (:build t) + :defer t + :init + (add-hook 'after-init-hook #'mu4e-alert-enable-notifications) + (add-hook 'after-init-hook #'mu4e-alert-enable-mode-line-display) + (mu4e-alert-set-default-style 'notifications) + :config + (setq mu4e-alert-interesting-mail-query "flag:unread")) #+end_src *** Nov @@ -1870,29 +1876,29 @@ it, I don’t need any other Epub reader on my computer! Plus this one is customizable and programmable, why would I use any other EPUB reader? #+begin_src emacs-lisp - (use-package nov - :straight (:build t) - :defer t - :mode ("\\.epub\\'" . nov-mode) - :config - (general-define-key - :keymaps 'nov-mode-map - :states 'normal - "SPC" nil - "c" #'nov-previous-document - "t" #'nov-scroll-up - "C-d" #'nov-scroll-up - "s" #'nov-scroll-down - "C-u" #'nov-scroll-down - "r" #'nov-next-document - "gm" #'nov-display-metadata - "gn" #'nov-next-document - "gp" #'nov-previous-document - "gr" #'nov-render-document - "gt" #'nov-goto-toc - "gv" #'nov-view-source - "gV" #'nov-view-content-source) - (setq nov-text-width 95)) +(use-package nov + :straight (:build t) + :defer t + :mode ("\\.epub\\'" . nov-mode) + :config + (general-define-key + :keymaps 'nov-mode-map + :states 'normal + "SPC" nil + "c" #'nov-previous-document + "t" #'nov-scroll-up + "C-d" #'nov-scroll-up + "s" #'nov-scroll-down + "C-u" #'nov-scroll-down + "r" #'nov-next-document + "gm" #'nov-display-metadata + "gn" #'nov-next-document + "gp" #'nov-previous-document + "gr" #'nov-render-document + "gt" #'nov-goto-toc + "gv" #'nov-view-source + "gV" #'nov-view-content-source) + (setq nov-text-width 95)) #+end_src *** PDF Tools @@ -1900,67 +1906,67 @@ reader? :CUSTOM_ID: Packages-Configuration-Applications-PDF-Toolsvqb1fl6184j0 :END: #+begin_src emacs-lisp - (use-package pdf-tools - :defer t - :magic ("%PDF" . pdf-view-mode) - :straight (:build t) - :mode (("\\.pdf\\'" . pdf-view-mode)) - :hook (pdf-tools-enabled . pdf-view-midnight-minor-mode) - :config - (progn - (with-eval-after-load 'pdf-view - (setq pdf-view-midnight-colors '("#d8dee9" . "#2e3440"))) - (general-define-key - :keymaps 'pdf-view-mode-map - "SPC" nil - "," nil) - (general-define-key - :states 'normal - :keymaps 'pdf-view-mode-map - "SPC" nil - "," nil - "y" #'pdf-view-kill-ring-save - "t" #'evil-collection-pdf-view-next-line-or-next-page - "s" #'evil-collection-pdf-view-previous-line-or-previous-page) - (general-define-key - :states 'motion - :keymaps 'pdf-view-mode-map - :prefix "," - "a" '(nil :which-key "annotations") - "aD" #'pdf-annot-delete - "at" #'pdf-annot-attachment-dired - "ah" #'pdf-annot-add-highlight-markup-annotation - "al" #'pdf-annot-list-annotations - "am" #'pdf-annot-markup-annotation - "ao" #'pdf-annot-add-strikeout-markup-annotation - "as" #'pdf-annot-add-squiggly-markup-annotation - "at" #'pdf-annot-add-text-annotation - "au" #'pdf-annot-add-underline-markup-annotation +(use-package pdf-tools + :defer t + :magic ("%PDF" . pdf-view-mode) + :straight (:build t) + :mode (("\\.pdf\\'" . pdf-view-mode)) + :hook (pdf-tools-enabled . pdf-view-midnight-minor-mode) + :config + (progn + (with-eval-after-load 'pdf-view + (setq pdf-view-midnight-colors '("#d8dee9" . "#2e3440"))) + (general-define-key + :keymaps 'pdf-view-mode-map + "SPC" nil + "," nil) + (general-define-key + :states 'normal + :keymaps 'pdf-view-mode-map + "SPC" nil + "," nil + "y" #'pdf-view-kill-ring-save + "t" #'evil-collection-pdf-view-next-line-or-next-page + "s" #'evil-collection-pdf-view-previous-line-or-previous-page) + (general-define-key + :states 'motion + :keymaps 'pdf-view-mode-map + :prefix "," + "a" '(nil :which-key "annotations") + "aD" #'pdf-annot-delete + "at" #'pdf-annot-attachment-dired + "ah" #'pdf-annot-add-highlight-markup-annotation + "al" #'pdf-annot-list-annotations + "am" #'pdf-annot-markup-annotation + "ao" #'pdf-annot-add-strikeout-markup-annotation + "as" #'pdf-annot-add-squiggly-markup-annotation + "at" #'pdf-annot-add-text-annotation + "au" #'pdf-annot-add-underline-markup-annotation - "f" '(nil :which-key "fit") - "fw" #'pdf-view-fit-width-to-window - "fh" #'pdf-view-fit-height-to-window - "fp" #'pdf-view-fit-page-to-window + "f" '(nil :which-key "fit") + "fw" #'pdf-view-fit-width-to-window + "fh" #'pdf-view-fit-height-to-window + "fp" #'pdf-view-fit-page-to-window - "s" '(nil :which-key "slice/search") - "sb" #'pdf-view-set-slice-from-bounding-box - "sm" #'pdf-view-set-slice-using-mouse - "sr" #'pdf-view-reset-slice - "ss" #'pdf-occur + "s" '(nil :which-key "slice/search") + "sb" #'pdf-view-set-slice-from-bounding-box + "sm" #'pdf-view-set-slice-using-mouse + "sr" #'pdf-view-reset-slice + "ss" #'pdf-occur - "o" 'pdf-outline - "m" 'pdf-view-midnight-minor-mode))) + "o" 'pdf-outline + "m" 'pdf-view-midnight-minor-mode))) #+end_src #+begin_src emacs-lisp - (use-package pdf-view-restore - :after pdf-tools - :hook (pdf-view-mode . pdf-view-restore-mode)) +(use-package pdf-view-restore + :after pdf-tools + :hook (pdf-view-mode . pdf-view-restore-mode)) #+end_src #+begin_src emacs-lisp - (setq pdf-view-restore-filename (expand-file-name ".tmp/pdf-view-restore" - user-emacs-directory)) +(setq pdf-view-restore-filename (expand-file-name ".tmp/pdf-view-restore" + user-emacs-directory)) #+end_src *** Project Management @@ -1978,62 +1984,62 @@ thing doesn’t happen with Magit, it’s pretty transparent but it still provides some awesome features and visualizations of what you are doing and what Git is doing! In short, I absolutely love it! #+begin_src emacs-lisp - (use-package magit - :straight (:build t) - :defer t - :custom - (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1) - :general - (:keymaps '(git-rebase-mode-map) - "C-t" #'evil-next-line - "C-s" #'evil-previous-line) - (:keymaps 'git-rebase-mode-map - :states 'normal - :prefix "," - "," #'with-editor-finish - "k" #'with-editor-cancel - "a" #'with-editor-cancel) - (:states 'normal - :prefix "SPC" - "g" '(nil :wk "git") - "gb" #'magit-blame - "gc" #'magit-clone - "gd" #'magit-dispatch - "gi" #'magit-init - "gs" #'magit-status - "gy" #'my/yadm - "gS" #'magit-stage-file - "gU" #'magit-unstage-file +(use-package magit + :straight (:build t) + :defer t + :custom + (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1) + :general + (:keymaps '(git-rebase-mode-map) + "C-t" #'evil-next-line + "C-s" #'evil-previous-line) + (:keymaps 'git-rebase-mode-map + :states 'normal + :prefix "," + "," #'with-editor-finish + "k" #'with-editor-cancel + "a" #'with-editor-cancel) + (:states 'normal + :prefix "SPC" + "g" '(nil :wk "git") + "gb" #'magit-blame + "gc" #'magit-clone + "gd" #'magit-dispatch + "gi" #'magit-init + "gs" #'magit-status + "gy" #'my/yadm + "gS" #'magit-stage-file + "gU" #'magit-unstage-file - "gf" '(nil :wk "file") - "gfd" #'magit-diff - "gfc" #'magit-file-checkout - "gfl" #'magit-file-dispatch - "gfF" #'magit-find-file)) + "gf" '(nil :wk "file") + "gfd" #'magit-diff + "gfc" #'magit-file-checkout + "gfl" #'magit-file-dispatch + "gfF" #'magit-find-file)) #+end_src [[https://github.com/alphapapa][Alphapapa]] also created an awesome package for Magit: magit-todos which display in the Magit buffer a list of TODOs found in the current project to remind you of what to do next. #+begin_src emacs-lisp - (use-package magit-todos - :straight (:build t) - :after magit - :config - (setq magit-todos-ignore-case t)) +(use-package magit-todos + :straight (:build t) + :after magit + :config + (setq magit-todos-ignore-case t)) #+end_src Finally, it is also possible to use Gitflow’s framework with Magit with ~magit-gitflow~: #+begin_src emacs-lisp - (use-package magit-gitflow - :defer t - :after magit - :straight (magit-gitflow :build t - :type git - :host github - :repo "jtatarik/magit-gitflow") - :hook (magit-mode . turn-on-magit-gitflow)) +(use-package magit-gitflow + :defer t + :after magit + :straight (magit-gitflow :build t + :type git + :host github + :repo "jtatarik/magit-gitflow") + :hook (magit-mode . turn-on-magit-gitflow)) #+end_src **** Forge @@ -2045,9 +2051,9 @@ with ~magit-gitflow~: - [[https://magit.vc/manual/forge/Token-Creation.html#Token-Creation][Token Creation]] - [[https://magit.vc/manual/ghub/Getting-Started.html#Getting-Started][Getting started]] #+begin_src emacs-lisp - (use-package forge - :after magit - :straight (:build t)) +(use-package forge + :after magit + :straight (:build t)) #+end_src **** Projectile @@ -2055,31 +2061,31 @@ with ~magit-gitflow~: :CUSTOM_ID: Packages-Configuration-Project-Management-Projectilesvr5fl6184j0 :END: #+begin_src emacs-lisp - (use-package ripgrep - :straight (:build t) - :defer t) +(use-package ripgrep + :straight (:build t) + :defer t) #+end_src #+begin_src emacs-lisp - (use-package projectile - :straight (:build t) - :defer t - :diminish projectile-mode - :config (projectile-mode) - :custom ((projectile-completion-system 'ivy)) - :bind-keymap - ("C-c p" . projectile-command-map) - :init - (setq projectile-switch-project-action #'projectile-dired) - :config - (add-to-list 'projectile-ignored-projects "~/")) +(use-package projectile + :straight (:build t) + :defer t + :diminish projectile-mode + :config (projectile-mode) + :custom ((projectile-completion-system 'ivy)) + :bind-keymap + ("C-c p" . projectile-command-map) + :init + (setq projectile-switch-project-action #'projectile-dired) + :config + (add-to-list 'projectile-ignored-projects "~/")) #+end_src #+begin_src emacs-lisp - (use-package counsel-projectile - :straight (:build t) - :after (counsel projectile) - :config (counsel-projectile-mode)) +(use-package counsel-projectile + :straight (:build t) + :after (counsel projectile) + :config (counsel-projectile-mode)) #+end_src *** Screenshot @@ -2087,12 +2093,12 @@ with ~magit-gitflow~: :CUSTOM_ID: Packages-Configuration-Applications-Screenshot96d1fl6184j0 :END: #+begin_src emacs-lisp - (use-package screenshot - :defer t - :straight (screenshot :build t - :type git - :host github - :repo "tecosaur/screenshot")) +(use-package screenshot + :defer t + :straight (screenshot :build t + :type git + :host github + :repo "tecosaur/screenshot")) #+end_src *** Shells @@ -2106,18 +2112,18 @@ with ~magit-gitflow~: Shell-pop allows the user to easily call for a new shell in a pop-up buffer. #+begin_src emacs-lisp - (use-package shell-pop - :defer t - :straight (:build t) - :custom - (shell-pop-default-directory "/home/phundrak") +(use-package shell-pop + :defer t + :straight (:build t) + :custom + (shell-pop-default-directory "/home/phundrak") (shell-pop-shell-type (quote ("eshell" "*eshell*" (lambda () (eshell shell-pop-term-shell))))) - (shell-pop-window-size 30) - (shell-pop-full-span nil) - (shell-pop-window-position "bottom") - (shell-pop-autocd-to-working-dir t) - (shell-pop-restore-window-configuration t) - (shell-pop-cleanup-buffer-at-process-exit t)) + (shell-pop-window-size 30) + (shell-pop-full-span nil) + (shell-pop-window-position "bottom") + (shell-pop-autocd-to-working-dir t) + (shell-pop-restore-window-configuration t) + (shell-pop-cleanup-buffer-at-process-exit t)) #+end_src **** VTerm @@ -2125,11 +2131,11 @@ buffer. :CUSTOM_ID: Packages-Configuration-Applications-Shells-VTermzfh1fl6184j0 :END: #+begin_src emacs-lisp - (use-package vterm - :defer t - :straight t - :config - (setq vterm-shell "/usr/bin/fish")) +(use-package vterm + :defer t + :straight t + :config + (setq vterm-shell "/usr/bin/fish")) #+end_src *** XWidgets Webkit Browser @@ -2137,33 +2143,33 @@ buffer. :CUSTOM_ID: Packages-Configuration-Applications-XWidgets-Webkit-Browsertui1fl6184j0 :END: #+begin_src emacs-lisp - (general-define-key - :keymaps 'xwidget-webkit-mode-map - :states 'normal - "" #'xwidget-webkit-scroll-down-line - "" #'xwidget-webkit-scroll-up-line +(general-define-key + :keymaps 'xwidget-webkit-mode-map + :states 'normal + "" #'xwidget-webkit-scroll-down-line + "" #'xwidget-webkit-scroll-up-line - "c" #'xwidget-webkit-scroll-backward - "t" #'xwidget-webkit-scroll-up-line - "s" #'xwidget-webkit-scroll-down-line - "r" #'xwidget-webkit-scroll-forward - "h" #'xwidget-webkit-goto-history - "j" nil - "k" nil - "l" nil + "c" #'xwidget-webkit-scroll-backward + "t" #'xwidget-webkit-scroll-up-line + "s" #'xwidget-webkit-scroll-down-line + "r" #'xwidget-webkit-scroll-forward + "h" #'xwidget-webkit-goto-history + "j" nil + "k" nil + "l" nil - "H" nil - "L" nil - "C-d" #'xwidget-webkit-scroll-up - "C-u" #'xwidget-webkit-scroll-down) + "H" nil + "L" nil + "C-d" #'xwidget-webkit-scroll-up + "C-u" #'xwidget-webkit-scroll-down) - (general-define-key - :keymaps 'xwidget-webkit-mode-map - :states 'normal - :prefix "," - "b" #'xwidget-webkit-back - "f" #'xwidget-webkit-forward - "r" #'xwidget-webkit-reload) +(general-define-key + :keymaps 'xwidget-webkit-mode-map + :states 'normal + :prefix "," + "b" #'xwidget-webkit-back + "f" #'xwidget-webkit-forward + "r" #'xwidget-webkit-reload) #+end_src *** Wttr.in @@ -2171,16 +2177,16 @@ buffer. :CUSTOM_ID: Packages-Configuration-Applications-Wttr-inpak1fl6184j0 :END: #+begin_src emacs-lisp - (use-package wttrin - :defer t - :straight (wttrin :build t - :local-repo "~/fromGIT/emacs-packages/emacs-wttrin" - :type git) - ;; :host github - ;; :repo "Phundrak/emacs-wttrin" - :config - (setq wttrin-default-cities '("Aubervilliers" "Paris" "Lyon" "Nonières" "Saint Agrève") - wttrin-use-metric t)) +(use-package wttrin + :defer t + :straight (wttrin :build t + :local-repo "~/fromGIT/emacs-packages/emacs-wttrin" + :type git) + ;; :host github + ;; :repo "Phundrak/emacs-wttrin" + :config + (setq wttrin-default-cities '("Aubervilliers" "Paris" "Lyon" "Nonières" "Saint Agrève") + wttrin-use-metric t)) #+end_src **** TODO Derive a major mode for wttrin :noexport: @@ -2197,14 +2203,14 @@ derived from ~fundamental-mode~ and get an associated keymap. First, I’ll define some keybindings for easily inserting pairs when editing text. #+begin_src emacs-lisp - (general-define-key - :states 'visual - "M-[" #'insert-pair - "M-{" #'insert-pair - "M-<" #'insert-pair - "M-'" #'insert-pair - "M-`" #'insert-pair - "M-\"" #'insert-pair) +(general-define-key + :states 'visual + "M-[" #'insert-pair + "M-{" #'insert-pair + "M-<" #'insert-pair + "M-'" #'insert-pair + "M-`" #'insert-pair + "M-\"" #'insert-pair) #+end_src *** Evil Nerd Commenter @@ -2214,9 +2220,9 @@ editing text. Emacs’ default commenting system is nice, but I don’t find it smart enough for me. #+begin_src emacs-lisp - (use-package evil-nerd-commenter - :after evil - :straight (:build t)) +(use-package evil-nerd-commenter + :after evil + :straight (:build t)) #+end_src *** Parinfer @@ -2232,14 +2238,14 @@ since been archived. New implementations then appeared, one of them is [[https://github.com/eraserhd/parinfer-rust][~parinfer-rust~]], obviously written in Rust, around which ~parinfer-rust-mode~ is built. #+begin_src emacs-lisp - (use-package parinfer-rust-mode - :defer t - :diminish parinfer-rust-mode - :hook emacs-lisp-mode common-lisp-mode scheme-mode - :init - (setq parinfer-rust-auto-download t - parinfer-rust-library-directory (concat user-emacs-directory - "parinfer-rust/"))) +(use-package parinfer-rust-mode + :defer t + :diminish parinfer-rust-mode + :hook emacs-lisp-mode common-lisp-mode scheme-mode + :init + (setq parinfer-rust-auto-download t + parinfer-rust-library-directory (concat user-emacs-directory + "parinfer-rust/"))) #+end_src *** Smartparens @@ -2252,10 +2258,10 @@ other programming languages that still uses parenthesis, but not as much as Lisp dialects; think for example C, C++, Rust, Javascript, and so on. #+begin_src emacs-lisp - (use-package smartparens - :defer t - :straight (:build t) - :hook (prog-mode . smartparens-mode)) +(use-package smartparens + :defer t + :straight (:build t) + :hook (prog-mode . smartparens-mode)) #+end_src *** ~string-edit~ @@ -2266,9 +2272,9 @@ so on. a string and get it automatically escaped for you. No more manually escaping your strings! #+begin_src emacs-lisp - (use-package string-edit - :defer t - :straight (:build t)) +(use-package string-edit + :defer t + :straight (:build t)) #+end_src *** Writeroom @@ -2279,14 +2285,14 @@ On the other hand, ~writeroom~ allows the user to enter a distraction-free mode of Emacs, and I like that! But the default width is a bit too small for me, and I prefer not to go fullscren. #+begin_src emacs-lisp - (use-package writeroom-mode - :defer t - :straight (:build t) - :config - (setq writeroom-width 100 - writeroom-fullscreen-effect nil - writeroom-maximize-window nil - writeroom-mode-line t)) +(use-package writeroom-mode + :defer t + :straight (:build t) + :config + (setq writeroom-width 100 + writeroom-fullscreen-effect nil + writeroom-maximize-window nil + writeroom-mode-line t)) #+end_src ** Emacs built-ins @@ -2307,21 +2313,21 @@ However, the only thing I lack still is thumbnails. In any case, I need still to make some tweaks in order to make it usable for me. #+begin_src emacs-lisp - (use-package dired - :straight (:type built-in) - :defer t - :hook (dired-mode . turn-on-gnus-dired-mode) - :general - (:keymaps 'dired-mode-map - :states 'normal - "(" #'dired-hide-details-mode - "n" #'evil-next-line - "p" #'evil-previous-line) - :config - (setq dired-dwim-target t - dired-recursive-copies t - dired-recursive-deletes t - dired-listing-switches "-ahl --group-directories-first")) +(use-package dired + :straight (:type built-in) + :defer t + :hook (dired-mode . turn-on-gnus-dired-mode) + :general + (:keymaps 'dired-mode-map + :states 'normal + "(" #'dired-hide-details-mode + "n" #'evil-next-line + "p" #'evil-previous-line) + :config + (setq dired-dwim-target t + dired-recursive-copies t + dired-recursive-deletes t + dired-listing-switches "-ahl --group-directories-first")) #+end_src Note that I am activating by default ~gnus-dired-mode~. This is just for @@ -2332,14 +2338,14 @@ each time I need it. Dired-x stands for “dired extra” which provides a couple more features that are for some reason not included in dired yet. #+begin_src emacs-lisp - (use-package dired-x - :straight (:type built-in) - :after dired - :commands (dired-jump dired-jump-other-window dired-omit-mode) - :general - (:keymaps 'dired-mode-map - :states 'normal - "«" #'dired-omit-mode)) +(use-package dired-x + :straight (:type built-in) + :after dired + :commands (dired-jump dired-jump-other-window dired-omit-mode) + :general + (:keymaps 'dired-mode-map + :states 'normal + "«" #'dired-omit-mode)) #+end_src ~dired-du~ provides the user with the option to be able to see the size @@ -2347,13 +2353,13 @@ of directories as they are, rather than just the size of their inode. However, I will not enable it by default as it can take some time to get the actual size of a directory. #+begin_src emacs-lisp - (use-package dired-du - :after dired - :straight (:build t) - :general - (:keymaps 'dired-mode-map - :states 'normal - "»" #'dired-du-mode)) +(use-package dired-du + :after dired + :straight (:build t) + :general + (:keymaps 'dired-mode-map + :states 'normal + "»" #'dired-du-mode)) #+end_src This package on the other hand provides Git information to the user in @@ -2361,37 +2367,37 @@ the current dired buffer in a similar way to how Github and Gitea display the latest commit message and its age about a file in the file tree. And by default, I want ~dired-git-info~ to hide file details. #+begin_src emacs-lisp - (use-package dired-git-info - :after dired - :hook (dired-after-reading . dired-git-info-auto-enable) - :general - (:keymaps 'dired-mode-map - :states 'normal - ")" #'dired-git-info-mode) - :config - (setq dgi-auto-hide-details-p t)) +(use-package dired-git-info + :after dired + :hook (dired-after-reading . dired-git-info-auto-enable) + :general + (:keymaps 'dired-mode-map + :states 'normal + ")" #'dired-git-info-mode) + :config + (setq dgi-auto-hide-details-p t)) #+end_src Diredfl makes dired colorful, and much more readable in my opinion. #+begin_src emacs-lisp - (use-package diredfl - :straight (:build t) - :after dired - :init - (diredfl-global-mode 1)) +(use-package diredfl + :straight (:build t) + :after dired + :init + (diredfl-global-mode 1)) #+end_src And let’s add some fancy icons in dired! #+begin_src emacs-lisp - (use-package all-the-icons-dired - :straight (:build t) - :hook (dired-mode . all-the-icons-dired-mode)) +(use-package all-the-icons-dired + :straight (:build t) + :hook (dired-mode . all-the-icons-dired-mode)) #+end_src #+begin_src emacs-lisp - (use-package image-dired+ - :after image-dired - :init (image-diredx-adjust-mode 1)) +(use-package image-dired+ + :after image-dired + :init (image-diredx-adjust-mode 1)) #+end_src *** Eshell @@ -2402,11 +2408,11 @@ Eshell is a built-in shell available from Emacs which I use almost as often as fish. Some adjustments are necessary to make it fit my taste though. #+begin_src emacs-lisp - (general-define-key - :keymaps 'eshell-mode-map - :states 'insert - "C-a" #'eshell-bol - "C-e" #'end-of-line) +(general-define-key + :keymaps 'eshell-mode-map + :states 'insert + "C-a" #'eshell-bol + "C-e" #'end-of-line) #+end_src **** Aliases @@ -2416,18 +2422,18 @@ though. First, let’s declare our list of “dumb” aliases we’ll use in Eshell. You can find them here. #+begin_src emacs-lisp - (setq eshell-aliases-file (expand-file-name "eshell-aliases" user-emacs-directory)) +(setq eshell-aliases-file (expand-file-name "eshell-aliases" user-emacs-directory)) #+end_src A couple of other aliases will be defined through custom Elisp functions, but first I’ll need a function for concatenating a shell command into a single string: #+begin_src emacs-lisp - (defun phundrak/concatenate-shell-command (&rest command) +(defun phundrak/concatenate-shell-command (&rest command) "Concatenate an eshell COMMAND into a single string. All elements of COMMAND will be joined in a single - space-separated string." - (string-join command " ")) +space-separated string." + (string-join command " ")) #+end_src I’ll also declare some aliases here, such as ~open~ and ~openo~ that @@ -2453,12 +2459,12 @@ or ~nano~ in Eshell, which is stupid: I’m already inside Emacs and I have all its power available instantly. So, let’s open each file passed to these commands. #+begin_src emacs-lisp - (defun eshell/emacs (&rest file) +(defun eshell/emacs (&rest file) "Open each FILE and kill eshell. - Old habits die hard." - (when file - (dolist (f (reverse file)) - (find-file f t)))) +Old habits die hard." + (when file + (dolist (f (reverse file)) + (find-file f t)))) #+end_src Finally, I’ll declare ~mkcd~ which allows the simultaneous creation of a @@ -2466,12 +2472,12 @@ directory and moving into this newly created directory. And of course, it will also work if the directory also exists or if parent directories don’t, similarly to the ~-p~ option passed to ~mkdir~. #+begin_src emacs-lisp - (defun eshell/mkcd (dir) +(defun eshell/mkcd (dir) "Create the directory DIR and move there. If the directory DIR doesn’t exist, create it and its parents - if needed, then move there." - (mkdir dir t) - (cd dir)) +if needed, then move there." + (mkdir dir t) + (cd dir)) #+end_src **** Autosuggestion @@ -2481,14 +2487,14 @@ If the directory DIR doesn’t exist, create it and its parents I really like fish’s autosuggestion feature, so let’s reproduce it here! #+begin_src emacs-lisp - (use-package esh-autosuggest - :defer t - :after eshell - :straight (:build t) - :hook (eshell-mode . esh-autosuggest-mode) - :general - (:keymaps 'esh-autosuggest-active-map - "C-e" #'company-complete-selection)) +(use-package esh-autosuggest + :defer t + :after eshell + :straight (:build t) + :hook (eshell-mode . esh-autosuggest-mode) + :general + (:keymaps 'esh-autosuggest-active-map + "C-e" #'company-complete-selection)) #+end_src **** Commands @@ -2499,32 +2505,32 @@ When I’m in Eshell, sometimes I wish to open multiple files at once in Emacs. For this, when I have several arguments for ~find-file~, I want to be able to open them all at once. Let’s modify ~find-file~ like so: #+BEGIN_SRC emacs-lisp - (defadvice find-file (around find-files activate) - "Also find all files within a list of files. This even works recursively." - (if (listp filename) - (cl-loop for f in filename do (find-file f wildcards)) - ad-do-it)) +(defadvice find-file (around find-files activate) + "Also find all files within a list of files. This even works recursively." + (if (listp filename) + (cl-loop for f in filename do (find-file f wildcards)) + ad-do-it)) #+END_SRC I also want to be able to have multiple instances of Eshell opened at once. For that, I declared the function ~eshell-new~ that does exactly that. #+begin_src emacs-lisp - (defun eshell-new () - "Open a new instance of eshell." - (interactive) - (eshell 'N)) +(defun eshell-new () + "Open a new instance of eshell." + (interactive) + (eshell 'N)) #+end_src A very useful command I use often in fish is ~z~, a port from bash’s and zsh’s command that allows to jump around directories based on how often we go in various directories. #+begin_src emacs-lisp - (use-package eshell-z - :defer t - :after eshell - :straight (:build t) - :hook (eshell-mode . (lambda () (require 'eshell-z)))) +(use-package eshell-z + :defer t + :after eshell + :straight (:build t) + :hook (eshell-mode . (lambda () (require 'eshell-z)))) #+end_src **** Environment Variables @@ -2535,20 +2541,20 @@ Some environment variables need to be correctly set so Eshell can correctly work. I would like to set two environment variables related to Dart development: the ~DART_SDK~ and ~ANDROID_HOME~ variables. #+BEGIN_SRC emacs-lisp - (setenv "DART_SDK" "/opt/dart-sdk/bin") - (setenv "ANDROID_HOME" (concat (getenv "HOME") "/Android/Sdk/")) +(setenv "DART_SDK" "/opt/dart-sdk/bin") +(setenv "ANDROID_HOME" (concat (getenv "HOME") "/Android/Sdk/")) #+END_SRC The ~EDITOR~ variable also needs to be set for git commands, especially the ~yadm~ commands. #+BEGIN_SRC emacs-lisp - (setenv "EDITOR" "emacsclient -c -a emacs") +(setenv "EDITOR" "emacsclient -c -a emacs") #+END_SRC Finally, for some specific situations I need ~SHELL~ to be set to something more standard than fish: #+begin_src emacs-lisp - (setenv "SHELL" "/bin/sh") +(setenv "SHELL" "/bin/sh") #+end_src **** Visual configuration @@ -2559,35 +2565,35 @@ I like to have at quick glance some information about my machine when I fire up a terminal. I haven’t found anything that does that the way I like it, so [[https://github.com/Phundrak/eshell-info-banner.el][I’ve written a package]]! #+begin_src emacs-lisp - (use-package eshell-info-banner - :defer t - :straight (eshell-info-banner :build t - :type git - :host github - :repo "phundrak/eshell-info-banner.el") - :hook (eshell-banner-load . eshell-info-banner-update-banner) - :config - (setq eshell-info-banner-width 80 - eshell-info-banner-partition-prefixes '("/dev" "zroot" "tank"))) +(use-package eshell-info-banner + :defer t + :straight (eshell-info-banner :build t + :type git + :host github + :repo "phundrak/eshell-info-banner.el") + :hook (eshell-banner-load . eshell-info-banner-update-banner) + :config + (setq eshell-info-banner-width 80 + eshell-info-banner-partition-prefixes '("/dev" "zroot" "tank"))) #+end_src Another feature I like is fish-like syntax highlight, which brings some more colors to Eshell. #+begin_src emacs-lisp - (use-package eshell-syntax-highlighting - :after esh-mode - :defer t - :config - (eshell-syntax-highlighting-global-mode +1)) +(use-package eshell-syntax-highlighting + :after esh-mode + :defer t + :config + (eshell-syntax-highlighting-global-mode +1)) #+end_src Powerline prompts are nice, git-aware prompts are even better! ~eshell-git-prompt~ is nice, but I prefer to write my own package for that. #+begin_src emacs-lisp - (use-package powerline-eshell - :load-path "~/fromGIT/emacs-packages/powerline-eshell.el/" - :after eshell) +(use-package powerline-eshell + :load-path "~/fromGIT/emacs-packages/powerline-eshell.el/" + :after eshell) #+end_src *** Info @@ -2599,39 +2605,39 @@ space bar is already bound to a function, ~Info-scroll-up~. Same goes for my local leader ~,~ which is bound to ~Info-index-next~. I don’t want that, so let’s unbind them: #+begin_src emacs-lisp - (general-define-key - :keymaps '(Info-mode-map) - "SPC" nil - "," nil) - (general-define-key - :keymaps '(Info-mode-map) - :states 'normal - "SPC" nil - "," nil) +(general-define-key + :keymaps '(Info-mode-map) + "SPC" nil + "," nil) +(general-define-key + :keymaps '(Info-mode-map) + :states 'normal + "SPC" nil + "," nil) #+end_src Alright, now that we correctly unbound them, my global leader key works again, and I’m free to use the comma as a local leader, so let’s do that: #+begin_src emacs-lisp - (general-define-key - :keymaps 'Info-mode-map - :states 'normal - "c" #'Info-prev - "t" #'evil-scroll-down - "s" #'evil-scroll-up - "r" #'Info-next) +(general-define-key + :keymaps 'Info-mode-map + :states 'normal + "c" #'Info-prev + "t" #'evil-scroll-down + "s" #'evil-scroll-up + "r" #'Info-next) - (general-define-key - :keymaps 'Info-mode-map - :states 'normal - :prefix "," - "?" #'Info-toc - "b" #'Info-history-back - "f" #'Info-history-forward - "m" #'Info-menu - "t" #'Info-top-node - "u" #'Info-up) +(general-define-key + :keymaps 'Info-mode-map + :states 'normal + :prefix "," + "?" #'Info-toc + "b" #'Info-history-back + "f" #'Info-history-forward + "m" #'Info-menu + "t" #'Info-top-node + "u" #'Info-up) #+end_src *** Tramp @@ -2643,7 +2649,7 @@ various hosts using various protocols, such as ~ssh~ and ~rsync~. However, I have some use-case for Tramp which are not supported natively. I will describe them here. #+begin_src emacs-lisp - (require 'tramp) +(require 'tramp) #+end_src **** Yadm @@ -2667,10 +2673,10 @@ how! Let’s just insert in my config this code snippet: I’ll also create a fuction for connecting to this new Tramp protocol: #+begin_src emacs-lisp - (defun my/yadm () - "Manage my dotfiles through TRAMP." - (interactive) - (magit-status "/yadm::")) +(defun my/yadm () + "Manage my dotfiles through TRAMP." + (interactive) + (magit-status "/yadm::")) #+end_src ** Making my life easier @@ -2688,22 +2694,22 @@ news! Also, no ~helm~ please! And for some reasons the keybindings are borked by default, so let’s redefine them, and let’s also rebind ~SPC~ to ~p~ since it would conflict with my main ~general~ prefix. #+begin_src emacs-lisp - (use-package bufler - :straight (bufler :build t - :files (:defaults (:exclude "helm-bufler.el"))) - :defer t - :general - (:keymaps 'bufler-list-mode-map - :states 'normal - "?" #'hydra:bufler/body - "g" #'bufler - "f" #'bufler-list-group-frame - "F" #'bufler-list-group-make-frame - "N" #'bufler-list-buffer-name-workspace - "k" #'bufler-list-buffer-kill - "p" #'bufler-list-buffer-peek - "s" #'bufler-list-buffer-save - "RET" #'bufler-list-buffer-switch)) +(use-package bufler + :straight (bufler :build t + :files (:defaults (:exclude "helm-bufler.el"))) + :defer t + :general + (:keymaps 'bufler-list-mode-map + :states 'normal + "?" #'hydra:bufler/body + "g" #'bufler + "f" #'bufler-list-group-frame + "F" #'bufler-list-group-make-frame + "N" #'bufler-list-buffer-name-workspace + "k" #'bufler-list-buffer-kill + "p" #'bufler-list-buffer-peek + "s" #'bufler-list-buffer-save + "RET" #'bufler-list-buffer-switch)) #+end_src *** Helpful @@ -2722,17 +2728,17 @@ enhances a couple of built-in functions from Emacs, namely: | ~describe-variable~ | ~helpful-variable~ | | #+begin_src emacs-lisp - (use-package helpful - :straight (:build t) - :after (counsel ivy) - :custom - (counsel-describe-function-function #'helpfull-callable) - (counsel-describe-variable-function #'helpfull-variable) - :bind - ([remap describe-function] . counsel-describe-function) - ([remap describe-command] . helpful-command) - ([remap describe-variable] . counsel-describe-variable) - ([remap describe-key] . helpful-key)) +(use-package helpful + :straight (:build t) + :after (counsel ivy) + :custom + (counsel-describe-function-function #'helpfull-callable) + (counsel-describe-variable-function #'helpfull-variable) + :bind + ([remap describe-function] . counsel-describe-function) + ([remap describe-command] . helpful-command) + ([remap describe-variable] . counsel-describe-variable) + ([remap describe-key] . helpful-key)) #+end_src ** Org-mode @@ -2751,75 +2757,76 @@ single document source is meant to be exported for both formats. And since org is an Emacs package, that also means it can be greatly extended however we like! #+begin_src emacs-lisp - (use-package org - :straight (org :build t - :type built-in) - :defer t - :commands (orgtbl-mode) - :hook ((org-mode . visual-line-mode) - (org-mode . org-num-mode)) - :custom-face - (org-macro ((t (:foreground "#b48ead")))) - :init - (auto-fill-mode -1) - :config - <> - (require 'ox-beamer) - (setq org-hide-leading-stars nil - org-hide-macro-markers t - org-ellipsis " ⤵" - org-image-actual-width 550 - org-redisplay-inline-images t - org-display-inline-images t - org-startup-with-inline-images "inlineimages" - org-pretty-entities t - org-fontify-whole-heading-line t - org-fontify-done-headline t - org-fontify-quote-and-verse-blocks t - org-startup-indented t - org-startup-align-all-tables t - org-use-property-inheritance t - org-list-allow-alphabetical t - org-M-RET-may-split-line nil - org-src-window-setup 'split-window-below - org-src-fontify-natively t - org-src-tab-acts-natively t - org-log-done 'time - org-directory "~/org" - org-default-notes-file (expand-file-name "notes.org" org-directory)) - <> - <> - <> - <> - <> - <> - <> - <> - <> - <> - <> - <> - <> - :general - (:states 'normal - :keymaps 'org-mode-map - "RET" 'org-open-at-point) - (:states 'normal - :prefix "," - :keymaps 'org-mode-map - <> - <> - <> - <> - <> - <> - <>) +(use-package org + :straight (org :build t + :type built-in) + :defer t + :commands (orgtbl-mode) + :hook ((org-mode . visual-line-mode) + (org-mode . org-num-mode)) + :custom-face + (org-macro ((t (:foreground "#b48ead")))) + :init + (auto-fill-mode -1) + :config + <> + (require 'ox-beamer) + (setq org-hide-leading-stars nil + org-hide-macro-markers t + org-ellipsis " ⤵" + org-image-actual-width 550 + org-redisplay-inline-images t + org-display-inline-images t + org-startup-with-inline-images "inlineimages" + org-pretty-entities t + org-fontify-whole-heading-line t + org-fontify-done-headline t + org-fontify-quote-and-verse-blocks t + org-startup-indented t + org-startup-align-all-tables t + org-use-property-inheritance t + org-list-allow-alphabetical t + org-M-RET-may-split-line nil + org-src-window-setup 'split-window-below + org-src-fontify-natively t + org-src-tab-acts-natively t + org-src-preserve-indentation t + org-log-done 'time + org-directory "~/org" + org-default-notes-file (expand-file-name "notes.org" org-directory)) + <> + <> + <> + <> + <> + <> + <> + <> + <> + <> + <> + <> + <> + :general + (:states 'normal + :keymaps 'org-mode-map + "RET" 'org-open-at-point) + (:states 'normal + :prefix "," + :keymaps 'org-mode-map + <> + <> + <> + <> + <> + <> + <>) - (:states 'normal - :keymaps 'org-src-mode-map - :prefix "," - "'" #'org-edit-src-exit - "k" #'org-edit-src-abort)) + (:states 'normal + :keymaps 'org-src-mode-map + :prefix "," + "'" #'org-edit-src-exit + "k" #'org-edit-src-abort)) #+end_src The main feature from ~evil-org~ that I love is how easy it is to modify @@ -2828,32 +2835,32 @@ the bépo layout (or Dvorak or Colemak if you are into that). But it also adds a ton of default keybindings which are just much more comfortable than the default ones you get with evil and org naked. #+begin_src emacs-lisp - (use-package evil-org - :straight (:build t) - :after org - :hook (org-mode . evil-org-mode) - :config - (setq-default evil-org-movement-bindings - '((up . "s") - (down . "t") - (left . "c") - (right . "r"))) - (evil-org-set-key-theme '(textobjects navigation calendar additional shift operators)) - (require 'evil-org-agenda) - (evil-org-agenda-set-keys)) +(use-package evil-org + :straight (:build t) + :after org + :hook (org-mode . evil-org-mode) + :config + (setq-default evil-org-movement-bindings + '((up . "s") + (down . "t") + (left . "c") + (right . "r"))) + (evil-org-set-key-theme '(textobjects navigation calendar additional shift operators)) + (require 'evil-org-agenda) + (evil-org-agenda-set-keys)) #+end_src This package is a small package I’ve written that helps me when writing conlanging documents, with features such as creating syntax trees, converting translitterated text to its native script, etc… #+begin_src emacs-lisp - (use-package conlanging - :straight (conlanging :build t - :type git - :host nil - :repo "https://labs.phundrak.com/phundrak/conlanging.el") - :after org - :defer t) +(use-package conlanging + :straight (conlanging :build t + :type git + :host nil + :repo "https://labs.phundrak.com/phundrak/conlanging.el") + :after org + :defer t) #+end_src Since very recently, the ~contrib/lisp/~ directory of org moved out of @@ -2862,11 +2869,11 @@ the main repository to [[https://git.sr.ht/~bzg/org-contrib][this repository]]. it. The main reason I want ~org-contrib~ is due to ~ox-extra~ that allow the usage of the ~:ignore:~ tag in org. #+begin_src emacs-lisp - (use-package org-contrib - :straight (:build t) - :init - (require 'ox-extra) - (ox-extras-activate '(latex-header-blocks ignore-headlines))) +(use-package org-contrib + :straight (:build t) + :init + (require 'ox-extra) + (ox-extras-activate '(latex-header-blocks ignore-headlines))) #+end_src *** Agenda @@ -2876,7 +2883,7 @@ the usage of the ~:ignore:~ tag in org. :END: #+name: org-agenda-files #+begin_src emacs-lisp - (setq-default org-agenda-files (list "~/org/agenda" "~/org/notes.org")) +(setq-default org-agenda-files (list "~/org/agenda" "~/org/notes.org")) #+end_src *** Behavior @@ -2889,41 +2896,41 @@ table of content of my files to quickly jump around my file (I have ~counsel-org-goto~ for that), but it is for creating table of contents for org files that will be hosted and viewable on Github. #+begin_src emacs-lisp - (use-package toc-org - :after org - :straight (:build t) - :init - (add-to-list 'org-tag-alist '("TOC" . ?T)) - :hook (org-mode . toc-org-enable) - :hook (markdown-mode . toc-org-enable)) +(use-package toc-org + :after org + :straight (:build t) + :init + (add-to-list 'org-tag-alist '("TOC" . ?T)) + :hook (org-mode . toc-org-enable) + :hook (markdown-mode . toc-org-enable)) #+end_src ~electric-mode~ also bothers me a lot when editing org files, so let’s deactivate it: #+name: org-behavior-electric #+begin_src emacs-lisp - (add-hook 'org-mode-hook (lambda () - (interactive) - (electric-indent-local-mode -1))) +(add-hook 'org-mode-hook (lambda () + (interactive) + (electric-indent-local-mode -1))) #+end_src As explained in my [[https://blog.phundrak.com/better-custom-ids-orgmode/][blog post]], org-mode is terrible with coming up with meaningful IDs for its headings. I actually wrote a package for this! #+begin_src emacs-lisp - (use-package org-unique-id - :straight (org-unique-id :build t - :type git - :host github - :repo "Phundrak/org-unique-id") - :defer t - :after org - :init - (add-hook 'org-mode-hook - (lambda () - (add-hook 'before-save-hook - (lambda () - (when (and (eq major-mode 'org-mode) - (eq buffer-read-only nil)) - (org-unique-id))))))) +(use-package org-unique-id + :straight (org-unique-id :build t + :type git + :host github + :repo "Phundrak/org-unique-id") + :defer t + :after org + :init + (add-hook 'org-mode-hook + (lambda () + (add-hook 'before-save-hook + (lambda () + (when (and (eq major-mode 'org-mode) + (eq buffer-read-only nil)) + (org-unique-id))))))) #+end_src *** Babel @@ -2934,15 +2941,15 @@ A package I use from time to time is ~ob-latex-as-png~ which allows me to easily convert a LaTeX snippet into a PNG, regardless of the exporter I use afterwards. Its installation is pretty simple: #+begin_src emacs-lisp - (use-package ob-latex-as-png - :straight (:build t) - :defer t) +(use-package ob-latex-as-png + :straight (:build t) + :defer t) #+end_src #+begin_src emacs-lisp - (use-package ob-restclient - :straight (:build t) - :defer t) +(use-package ob-restclient + :straight (:build t) + :defer t) #+end_src One of the amazing features of org-mode is its literary programming capacities @@ -2965,11 +2972,11 @@ activated. Here are the languages I activated in my Org-mode configuration: #+header: :cache yes :results replace #+header: :var languages=org-babel-languages-table[,0] #+BEGIN_SRC emacs-lisp :exports none - (format "'(%s)" - (mapconcat (lambda ($language) - (format "(%s . t)" $language)) - languages - "\n ")) +(format "'(%s)" + (mapconcat (lambda ($language) + (format "(%s . t)" $language)) + languages + "\n ")) #+END_SRC #+RESULTS[52f5db378c4060c5ce47e6228e95feefba4fe24d]: org-babel-languages-gen @@ -2991,9 +2998,9 @@ activated. Here are the languages I activated in my Org-mode configuration: The corresponding code is as follows: #+NAME: org-babel-load-languages #+BEGIN_SRC emacs-lisp :noweb yes :tangle no - (org-babel-do-load-languages - 'org-babel-load-languages - <>) +(org-babel-do-load-languages + 'org-babel-load-languages + <>) #+END_SRC *** File export @@ -3007,7 +3014,7 @@ org files as a regular character and not a markup one, especially when describing phonetics evolution. So, let’s disable it: #+NAME: org-use-sub-superscripts #+BEGIN_SRC emacs-lisp :tangle no - (setq org-use-sub-superscripts (quote {})) +(setq org-use-sub-superscripts (quote {})) #+END_SRC @@ -3018,9 +3025,9 @@ describing phonetics evolution. So, let’s disable it: A backend for exporting files through org I like is ~ox-epub~ which, as you can guess, exports org files to the [[https://www.w3.org/publishing/epub32/][Epub format]]. #+begin_src emacs-lisp - (use-package ox-epub - :after ox - :straight (:build t)) +(use-package ox-epub + :after ox + :straight (:build t)) #+end_src **** HTML @@ -3031,19 +3038,19 @@ For Reveal.JS exports, I need to set where to find the framework by default: #+NAME: org-re-reveal-root #+BEGIN_SRC emacs-lisp - (setq org-re-reveal-root "https://cdn.jsdelivr.net/npm/reveal.js") +(setq org-re-reveal-root "https://cdn.jsdelivr.net/npm/reveal.js") #+END_SRC On HTML exports, Org-mode tries to include a validation link for the exported HTML. Let’s disable that since I never use it. #+NAME: org-html-validation #+BEGIN_SRC emacs-lisp - (setq org-html-validation-link nil) +(setq org-html-validation-link nil) #+END_SRC #+begin_src emacs-lisp - (use-package htmlize - :defer t) +(use-package htmlize + :defer t) #+end_src This package allows for live-previewing the HTML export of an org @@ -3051,23 +3058,23 @@ buffer in an XWidget Webkit browser window. But when testing it, it’s not great for large org files, I should keep its usage for smaller org files. #+begin_src emacs-lisp - (use-package preview-org-html-mode - :defer t - :after org - :straight (preview-org-html-mode :build t - :type git - :host github - :repo "jakebox/preview-org-html-mode") - :general - (:keymaps '(org-mode-map) - :states 'normal - :prefix "," - "P" '(:ignore :which-key "preview") - "Ph" #'preview-org-html-mode - "Pr" #'preview-org-html-refresh - "Pp" #'preview-org-html-pop-window-to-frame) - :config - (setq preview-org-html-refresh-configuration 'save)) +(use-package preview-org-html-mode + :defer t + :after org + :straight (preview-org-html-mode :build t + :type git + :host github + :repo "jakebox/preview-org-html-mode") + :general + (:keymaps '(org-mode-map) + :states 'normal + :prefix "," + "P" '(:ignore :which-key "preview") + "Ph" #'preview-org-html-mode + "Pr" #'preview-org-html-refresh + "Pp" #'preview-org-html-pop-window-to-frame) + :config + (setq preview-org-html-refresh-configuration 'save)) #+end_src **** LaTeX @@ -3079,14 +3086,14 @@ with XeLaTeX only. This implies the modification of the following variable: #+NAME: org-latex-compiler #+BEGIN_SRC emacs-lisp - (setq org-latex-compiler "xelatex") +(setq org-latex-compiler "xelatex") #+END_SRC I also want to get by default ~minted~ for LaTeX listings so I can have syntax highlights: #+NAME: org-latex-listings #+BEGIN_SRC emacs-lisp - (setq org-latex-listings 'minted) +(setq org-latex-listings 'minted) #+END_SRC The default packages break my LaTeX exports: for some reasons, images @@ -3101,35 +3108,35 @@ packages: - and ~tabularx~ for tabulars with adjustable columns #+NAME: org-latex-default-packages #+BEGIN_SRC emacs-lisp - (dolist (package '(("AUTO" "inputenc" t ("pdflatex")) - ("T1" "fontenc" t ("pdflatex")) - ("" "grffile" t))) - (delete package org-latex-default-packages-alist)) +(dolist (package '(("AUTO" "inputenc" t ("pdflatex")) + ("T1" "fontenc" t ("pdflatex")) + ("" "grffile" t))) + (delete package org-latex-default-packages-alist)) - (dolist (package '(("" "minted") - ("capitalize" "cleveref") - ("" "svg") - ("" "booktabs") - ("" "tabularx"))) - (add-to-list 'org-latex-default-packages-alist package t)) +(dolist (package '(("" "minted") + ("capitalize" "cleveref") + ("" "svg") + ("" "booktabs") + ("" "tabularx"))) + (add-to-list 'org-latex-default-packages-alist package t)) - (setq org-latex-reference-command "\\cref{%s}") +(setq org-latex-reference-command "\\cref{%s}") #+END_SRC By the way, reference links in LaTeX should be written in this format, since we are using ~cleveref~: #+NAME: org-export-latex-hyperref-format #+BEGIN_SRC emacs-lisp - (setq org-export-latex-hyperref-format "\\ref{%s}") +(setq org-export-latex-hyperref-format "\\ref{%s}") #+END_SRC And Minted should be default break lines if a line is too long: #+name: org-export-latex-minted-options #+begin_src emacs-lisp - (setq org-latex-minted-options '(("breaklines") - ("tabsize" "2") - ("frame" "single") - ("autogobble"))) +(setq org-latex-minted-options '(("breaklines") + ("tabsize" "2") + ("frame" "single") + ("autogobble"))) #+end_src When it comes to the export itself, the latex file needs to be @@ -3137,19 +3144,19 @@ processed several times through XeLaTeX in order to get some references right. Don’t forget to also run bibtex! #+NAME: org-latex-pdf-process #+BEGIN_SRC emacs-lisp - (setq org-latex-pdf-process - '("xelatex -8bit -shell-escape -interaction nonstopmode -output-directory %o %f" - "bibtex %b" - "xelatex -8bit -shell-escape -interaction nonstopmode -output-directory %o %f" - "xelatex -8bit -shell-escape -interaction nonstopmode -output-directory %o %f")) +(setq org-latex-pdf-process + '("xelatex -8bit -shell-escape -interaction nonstopmode -output-directory %o %f" + "bibtex %b" + "xelatex -8bit -shell-escape -interaction nonstopmode -output-directory %o %f" + "xelatex -8bit -shell-escape -interaction nonstopmode -output-directory %o %f")) #+END_SRC Finally, org-mode is supposed to automatically clean logfiles after it exports an org file to LaTeX. However, it misses a few, so I need to add their extension like so: #+begin_src emacs-lisp - (dolist (ext '("bbl" "lot")) - (add-to-list 'org-latex-logfiles-extensions ext t)) +(dolist (ext '("bbl" "lot")) + (add-to-list 'org-latex-logfiles-extensions ext t)) #+end_src **** Markdown @@ -3163,9 +3170,9 @@ supports some extra HTML to make our files extra spicy! And lucky me, there’s a package for exporting my org files to Github-flavored Markdown! #+begin_src emacs-lisp - (use-package ox-gfm - :after ox - :straight (:build t)) +(use-package ox-gfm + :after ox + :straight (:build t)) #+end_src **** SSH Config @@ -3176,9 +3183,9 @@ Yet another exporter I enjoy is [[https://github.com/dantecatalfamo/ox-ssh][~ox- ~$HOME/.ssh/config~ file. You won’t find my org file for managing my servers on my repos though. #+begin_src emacs-lisp - (use-package ox-ssh - :after ox - :straight (:build t)) +(use-package ox-ssh + :after ox + :straight (:build t)) #+end_src *** Keybindings @@ -3226,21 +3233,21 @@ code blocks and interact with them. This code block was inspired by one you can find in Spacemacs. #+name: org-hydra-babel #+begin_src emacs-lisp :tangle no - (defhydra org-babel-transient () - " - ^Navigate^ ^Interact - ^^^^^^^^^^^------------------------------------------ - [_t_/_s_] navigate src blocs [_x_] execute src block - [_g_]^^ goto named block [_'_] edit src block - [_z_]^^ recenter screen [_q_] quit +(defhydra org-babel-transient () " - ("q" nil :exit t) - ("t" org-babel-next-src-block) - ("s" org-babel-previous-src-block) - ("g" org-babel-goto-named-src-block) - ("z" recenter-top-bottom) - ("x" org-babel-execute-maybe) - ("'" org-edit-special :exit t)) +^Navigate^ ^Interact +^^^^^^^^^^^------------------------------------------ +[_t_/_s_] navigate src blocs [_x_] execute src block +[_g_]^^ goto named block [_'_] edit src block +[_z_]^^ recenter screen [_q_] quit +" + ("q" nil :exit t) + ("t" org-babel-next-src-block) + ("s" org-babel-previous-src-block) + ("g" org-babel-goto-named-src-block) + ("z" recenter-top-bottom) + ("x" org-babel-execute-maybe) + ("'" org-edit-special :exit t)) #+end_src We next have keybindings related to org-mode’s agenda capabilities. We @@ -3335,36 +3342,36 @@ exports. Below is the declaration of the ~conlang~ LaTeX class: #+NAME: org-latex-class-conlang #+BEGIN_SRC emacs-lisp - '("conlang" - "\\documentclass{book}" - ("\\chapter{%s}" . "\\chapter*{%s}") - ("\\section{%s}" . "\\section*{%s}") - ("\\subsection{%s}" . "\\subsection*{%s}") - ("\\subsubsection{%s}" . "\\subsubsection*{%s}")) +'("conlang" + "\\documentclass{book}" + ("\\chapter{%s}" . "\\chapter*{%s}") + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}")) #+END_SRC And here is the declaration of the ~beamer~ class: #+NAME: org-latex-class-beamer #+BEGIN_SRC emacs-lisp - `("beamer" - ,(concat "\\documentclass[presentation]{beamer}\n" - "[DEFAULT-PACKAGES]" - "[PACKAGES]" - "[EXTRA]\n") - ("\\section{%s}" . "\\section*{%s}") - ("\\subsection{%s}" . "\\subsection*{%s}") - ("\\subsubsection{%s}" . "\\subsubsection*{%s}")) +`("beamer" + ,(concat "\\documentclass[presentation]{beamer}\n" + "[DEFAULT-PACKAGES]" + "[PACKAGES]" + "[EXTRA]\n") + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}")) #+END_SRC Both these classes have to be added to ~org-latex-classes~ like so: #+NAME: org-latex-classes #+BEGIN_SRC emacs-lisp :noweb yes - (eval-after-load "ox-latex" - '(progn - (add-to-list 'org-latex-classes - <>) - (add-to-list 'org-latex-classes - <>))) +(eval-after-load "ox-latex" + '(progn + (add-to-list 'org-latex-classes + <>) + (add-to-list 'org-latex-classes + <>))) #+END_SRC *** Projects @@ -3377,17 +3384,17 @@ easily publish a bunch of org files to a remote location. Here is the current declaration of my projects, which will be detailed later: #+NAME: org-publish-projects #+BEGIN_SRC emacs-lisp :noweb yes - <> - <> - (setq org-publish-project-alist - `( - <> - <> - <> - <> - <> - <> - <>)) +<> +<> +(setq org-publish-project-alist + `( + <> + <> + <> + <> + <> + <> + <>)) #+END_SRC **** Configuration website @@ -3405,18 +3412,18 @@ manually, but now I can change all three values at the same time without a hasle. #+NAME: org-proj-config-setup #+BEGIN_SRC emacs-lisp - (defvar phundrak//projects-config-target - "/ssh:Tilo:~/www/phundrak.com/config" - "Points to where exported files for config.phundrak.com should be put.") - (defvar phundrak//projects-config-source - "~/org/config/" - "Points to where the sources for config.phundrak.com are.") - (defvar phundrak//projects-config-language - "en" - "Language of the website config.phundrak.com.") - (defvar phundrak//projects-config-recursive - t - "Defines whether subdirectories should be parsed for config.phundrak.com.") +(defvar phundrak//projects-config-target + "/ssh:Tilo:~/www/phundrak.com/config" + "Points to where exported files for config.phundrak.com should be put.") +(defvar phundrak//projects-config-source + "~/org/config/" + "Points to where the sources for config.phundrak.com are.") +(defvar phundrak//projects-config-language + "en" + "Language of the website config.phundrak.com.") +(defvar phundrak//projects-config-recursive + t + "Defines whether subdirectories should be parsed for config.phundrak.com.") #+END_SRC Now, here is my configuration. In this snippet, my org files located in my @@ -3426,37 +3433,37 @@ automatically generated, which comes in handy with the online sitemap that is available through the navigation bar. #+NAME: org-proj-config-html #+BEGIN_SRC emacs-lisp - ("config-website-org" - :base-directory ,phundrak//projects-config-source - :base-extension "org" - :publishing-directory ,phundrak//projects-config-target - :recursive ,phundrak//projects-config-recursive - :language ,phundrak//projects-config-language - :publishing-function org-html-publish-to-html - :headline-levels 5 - :auto-sitemap t - :auto-preamble t) +("config-website-org" + :base-directory ,phundrak//projects-config-source + :base-extension "org" + :publishing-directory ,phundrak//projects-config-target + :recursive ,phundrak//projects-config-recursive + :language ,phundrak//projects-config-language + :publishing-function org-html-publish-to-html + :headline-levels 5 + :auto-sitemap t + :auto-preamble t) #+END_SRC We also have the component for all the static files needed to run the website (mostly images tbh). #+NAME: org-proj-config-static #+BEGIN_SRC emacs-lisp - ("config-website-static" - :base-directory ,phundrak//projects-config-source - :base-extension "png\\|jpg\\|gif\\|webp\\|svg\\|jpeg\\|ttf\\|woff\\|txt\\|epub\\|md" - :publishing-directory ,phundrak//projects-config-target - :recursive ,phundrak//projects-config-recursive - :language ,phundrak//projects-config-language - :publishing-function org-publish-attachment) +("config-website-static" + :base-directory ,phundrak//projects-config-source + :base-extension "png\\|jpg\\|gif\\|webp\\|svg\\|jpeg\\|ttf\\|woff\\|txt\\|epub\\|md" + :publishing-directory ,phundrak//projects-config-target + :recursive ,phundrak//projects-config-recursive + :language ,phundrak//projects-config-language + :publishing-function org-publish-attachment) #+END_SRC The project is then defined like so: #+NAME: org-proj-config #+BEGIN_SRC emacs-lisp - ("config-website" - :components ("config-website-org" - "config-website-static")) +("config-website" + :components ("config-website-org" + "config-website-static")) #+END_SRC **** Linguistics website @@ -3467,71 +3474,71 @@ My linguistics website is made out of three projects. As for the previous project, let’s declare the common values for these. #+NAME: org-proj-lang-setup #+BEGIN_SRC emacs-lisp - (defvar phundrak//projects-conlanging-target +(defvar phundrak//projects-conlanging-target "/ssh:Tilo:~/www/phundrak.com/langue/" - "Points to where exported files for langue.phundrak.com should be put") - (defvar phundrak//projects-conlanging-source - "~/Documents/conlanging/content/" - "Points to where the sources for langue.phundrak.com are") - (defvar phundrak//projects-conlanging-language - "fr" - "Language of langue.phundrak.com") - (defvar phundrak//projects-conlanging-recursive - t - "Defines whether subdirectories should be parsed for langue.phundrak.com") + "Points to where exported files for langue.phundrak.com should be put") +(defvar phundrak//projects-conlanging-source + "~/Documents/conlanging/content/" + "Points to where the sources for langue.phundrak.com are") +(defvar phundrak//projects-conlanging-language + "fr" + "Language of langue.phundrak.com") +(defvar phundrak//projects-conlanging-recursive + t + "Defines whether subdirectories should be parsed for langue.phundrak.com") #+END_SRC The first component is the one generating the HTML files from the org files. #+NAME: org-proj-lang-html #+BEGIN_SRC emacs-lisp - ("langue-phundrak-com-org" - :base-directory ,phundrak//projects-conlanging-source - :base-extension "org" - :exclude "\\./\\(CONTRIB\\|README\\|head\\|temp\\|svg-ink\\).*" - :publishing-directory ,phundrak//projects-conlanging-target - :recursive ,phundrak//projects-conlanging-recursive - :language ,phundrak//projects-conlanging-language - :publishing-function org-html-publish-to-html - :headline-levels 5 - :auto-sitemap t - :auto-preamble t) +("langue-phundrak-com-org" + :base-directory ,phundrak//projects-conlanging-source + :base-extension "org" + :exclude "\\./\\(CONTRIB\\|README\\|head\\|temp\\|svg-ink\\).*" + :publishing-directory ,phundrak//projects-conlanging-target + :recursive ,phundrak//projects-conlanging-recursive + :language ,phundrak//projects-conlanging-language + :publishing-function org-html-publish-to-html + :headline-levels 5 + :auto-sitemap t + :auto-preamble t) #+END_SRC We also have the component for the LaTeX and PDF part of the website: #+NAME: org-proj-lang-pdf #+BEGIN_SRC emacs-lisp - ("langue-phundrak-com-pdf" - :base-directory ,phundrak//projects-conlanging-source - :base-extension "org" - :exclude "\\./\\(CONTRIB\\|README\\|index\\|head\\|temp\\|svg-ink\\).*" - :publishing-directory ,phundrak//projects-conlanging-target - :recursive ,phundrak//projects-conlanging-recursive - :language ,phundrak//projects-conlanging-language - :publishing-function org-latex-publish-to-pdf - :headline-levels 5 - :auto-preamble t) +("langue-phundrak-com-pdf" + :base-directory ,phundrak//projects-conlanging-source + :base-extension "org" + :exclude "\\./\\(CONTRIB\\|README\\|index\\|head\\|temp\\|svg-ink\\).*" + :publishing-directory ,phundrak//projects-conlanging-target + :recursive ,phundrak//projects-conlanging-recursive + :language ,phundrak//projects-conlanging-language + :publishing-function org-latex-publish-to-pdf + :headline-levels 5 + :auto-preamble t) #+END_SRC And lastly, we have the component for all the static files needed to run the website: #+NAME: org-proj-lang-static #+BEGIN_SRC emacs-lisp - ("langue-phundrak-com-static" - :base-directory ,phundrak//projects-conlanging-source - :base-extension "png\\|jpg\\|gif\\|webp\\|svg\\|jpeg\\|ttf\\|woff\\|txt\\|epub" - :publishing-directory ,phundrak//projects-conlanging-target - :recursive ,phundrak//projects-conlanging-recursive - :language ,phundrak//projects-conlanging-language - :publishing-function org-publish-attachment) +("langue-phundrak-com-static" + :base-directory ,phundrak//projects-conlanging-source + :base-extension "png\\|jpg\\|gif\\|webp\\|svg\\|jpeg\\|ttf\\|woff\\|txt\\|epub" + :publishing-directory ,phundrak//projects-conlanging-target + :recursive ,phundrak//projects-conlanging-recursive + :language ,phundrak//projects-conlanging-language + :publishing-function org-publish-attachment) #+END_SRC The project is then defined like so: #+NAME: org-proj-lang #+BEGIN_SRC emacs-lisp - ("langue-phundrak-com" - :components ("langue-phundrak-com-org" - "langue-phundrak-com-static" - "langue-phundrak-com-pdf")) +("langue-phundrak-com" + :components ("langue-phundrak-com-org" + "langue-phundrak-com-static" + "langue-phundrak-com-pdf")) #+END_SRC *** Org-ref and Bibtex configuration @@ -3539,88 +3546,88 @@ The project is then defined like so: :CUSTOM_ID: Packages-Configuration-Org-mode-org-ref-1h586cd085j0 :END: #+begin_src emacs-lisp - (use-package reftex - :commands turn-on-reftex - :init (setq reftex-default-bibliography "~/org/bibliography/references.bib" - reftex-plug-into-AUCTeX t)) +(use-package reftex + :commands turn-on-reftex + :init (setq reftex-default-bibliography "~/org/bibliography/references.bib" + reftex-plug-into-AUCTeX t)) #+end_src #+begin_src emacs-lisp - (use-package org-ref - :straight (:build t) - :after (org ox-bibtex) - :demand t - :custom-face - (org-ref-cite-face ((t (:weight bold)))) - :init - (setq org-ref-completion-library 'org-ref-ivy-cite - org-ref-bibliography-notes "~/org/bibliography/notes.org" - org-ref-default-bibliography "~/org/bibliography/references.bib" - org-ref-pdf-directory "~/org/bibliography/bibtex-pdfs/" - org-latex-logfiles-extensions '("lof" "lot" "aux" "idx" "out" "log" "fbd_latexmk" - "toc" "nav" "snm" "vrb" "dvi" "blg" "brf" "bflsb" - "entoc" "ps" "spl" "bbl" "pygtex" "pygstyle")) - (add-hook 'org-mode-hook (lambda () (require 'org-ref))) - :config - (setq bibtex-completion-pdf-field "file") - (general-define-key +(use-package org-ref + :straight (:build t) + :after (org ox-bibtex) + :demand t + :custom-face + (org-ref-cite-face ((t (:weight bold)))) + :init + (setq org-ref-completion-library 'org-ref-ivy-cite + org-ref-bibliography-notes "~/org/bibliography/notes.org" + org-ref-default-bibliography "~/org/bibliography/references.bib" + org-ref-pdf-directory "~/org/bibliography/bibtex-pdfs/" + org-latex-logfiles-extensions '("lof" "lot" "aux" "idx" "out" "log" "fbd_latexmk" + "toc" "nav" "snm" "vrb" "dvi" "blg" "brf" "bflsb" + "entoc" "ps" "spl" "bbl" "pygtex" "pygstyle")) + (add-hook 'org-mode-hook (lambda () (require 'org-ref))) + :config + (setq bibtex-completion-pdf-field "file") + (general-define-key + :keymaps '(bibtex-mode-map) + :states 'normal + "C-t" #'org-ref-bibtex-next-entry + "C-s" #'org-ref-bibtex-previous-entry + "gt" #'org-ref-bibtex-next-entry + "gs" #'org-ref-bibtex-previous-entry) + (general-define-key + :keymaps '(bibtex-mode-map) + :states 'normal + :prefix "," + ;; Navigation + "t" #'org-ref-bibtex-next-entry + "s" #'org-ref-bibtex-previous-entry + + ;; Open + "b" #'org-ref-open-in-browser + "n" #'org-ref-open-bibtex-notes + "p" #'org-ref-open-bibtex-pdf + + ;; Misc + "h" #'org-ref-bibtex-hydra/body + "i" #'org-ref-bibtex-hydra/org-ref-bibtex-new-entry/body-and-exit + "s" #'org-ref-sort-bibtex-entry + + "l" '(:ignore :which-key "lookup") + "la" #'arxiv-add-bibtex-entry + "lA" #'arxiv-get-pdf-add-bibtex-entry + "ld" #'doi-utils-add-bibtex-entry-from-doi + "li" #'isbn-to-bibtex + "lp" #'pubmed-insert-bibtex-from-pmid) + (general-define-key + :keymaps '(org-mode-map) + :states 'normal + :prefix "," + "ic" #'org-ref-insert-link)) +#+end_src + +#+begin_src emacs-lisp +(use-package ivy-bibtex + :defer t + :straight (:build t) + :config + (setq org-ref-bibliography-notes "~/org/bibliography/notes.org" + org-ref-default-bibliography "~/org/bibliography/references.bib" + org-ref-pdf-directory "~/org/bibliography/bibtex-pdfs/" + bibtex-completion-pdf-open-function #'find-file) + + (general-define-key :keymaps '(bibtex-mode-map) :states 'normal - "C-t" #'org-ref-bibtex-next-entry - "C-s" #'org-ref-bibtex-previous-entry - "gt" #'org-ref-bibtex-next-entry - "gs" #'org-ref-bibtex-previous-entry) - (general-define-key - :keymaps '(bibtex-mode-map) - :states 'normal - :prefix "," - ;; Navigation - "t" #'org-ref-bibtex-next-entry - "s" #'org-ref-bibtex-previous-entry - - ;; Open - "b" #'org-ref-open-in-browser - "n" #'org-ref-open-bibtex-notes - "p" #'org-ref-open-bibtex-pdf - - ;; Misc - "h" #'org-ref-bibtex-hydra/body - "i" #'org-ref-bibtex-hydra/org-ref-bibtex-new-entry/body-and-exit - "s" #'org-ref-sort-bibtex-entry - - "l" '(:ignore :which-key "lookup") - "la" #'arxiv-add-bibtex-entry - "lA" #'arxiv-get-pdf-add-bibtex-entry - "ld" #'doi-utils-add-bibtex-entry-from-doi - "li" #'isbn-to-bibtex - "lp" #'pubmed-insert-bibtex-from-pmid) - (general-define-key - :keymaps '(org-mode-map) - :states 'normal - :prefix "," - "ic" #'org-ref-insert-link)) + :prefix "SPC" + "m" #'ivy-bibtex)) #+end_src #+begin_src emacs-lisp - (use-package ivy-bibtex - :defer t - :straight (:build t) - :config - (setq org-ref-bibliography-notes "~/org/bibliography/notes.org" - org-ref-default-bibliography "~/org/bibliography/references.bib" - org-ref-pdf-directory "~/org/bibliography/bibtex-pdfs/" - bibtex-completion-pdf-open-function #'find-file) - - (general-define-key - :keymaps '(bibtex-mode-map) - :states 'normal - :prefix "SPC" - "m" #'ivy-bibtex)) -#+end_src - -#+begin_src emacs-lisp - (after! org - (require 'org-ref)) +(after! org + (require 'org-ref)) #+end_src *** Visual Configuration @@ -3634,27 +3641,27 @@ font enabled. *BUT*, these modes can also require some fixed-pitch fonts for some elements of the buffer, such as code blocks with org-mode. ~mixed-pitch~ comes to the rescue! #+begin_src emacs-lisp - (use-package mixed-pitch - :after org - :straight t - :hook - (org-mode . mixed-pitch-mode) - :config - (add-hook 'org-agenda-mode-hook (lambda () (mixed-pitch-mode -1)))) +(use-package mixed-pitch + :after org + :straight t + :hook + (org-mode . mixed-pitch-mode) + :config + (add-hook 'org-agenda-mode-hook (lambda () (mixed-pitch-mode -1)))) #+end_src With this, I also use ~org-pretty-tables~ in order to use some capabilities of Unicode in order to make tables nicer to look at. #+begin_src emacs-lisp - (use-package org-pretty-table - :defer t - :after org - :straight (org-pretty-table :type git - :host github - :repo "Fuco1/org-pretty-table" - :build t) - :hook (org-mode . org-pretty-table-mode) - :commands (org-pretty-table-mode global-org-pretty-table-mode)) +(use-package org-pretty-table + :defer t + :after org + :straight (org-pretty-table :type git + :host github + :repo "Fuco1/org-pretty-table" + :build t) + :hook (org-mode . org-pretty-table-mode) + :commands (org-pretty-table-mode global-org-pretty-table-mode)) #+end_src I have an issue with org-mode’s emphasis markers: I find them ugly. I @@ -3665,28 +3672,28 @@ emphasized region. ~org-appear~ fixes this issue so that it shows the emphasis markers only when the cursor is in the emphasized region, otherwise they will remain hidden! Very cool! #+begin_src emacs-lisp - (use-package org-appear - :after org - :straight (:build t) - :hook (org-mode . org-appear-mode) - :config - (setq org-appear-autoemphasis t - org-hide-emphasis-markers t - org-appear-autolinks t - org-appear-autoentities t - org-appear-autosubmarkers t) - (run-at-time nil nil #'org-appear--set-elements)) +(use-package org-appear + :after org + :straight (:build t) + :hook (org-mode . org-appear-mode) + :config + (setq org-appear-autoemphasis t + org-hide-emphasis-markers t + org-appear-autolinks t + org-appear-autoentities t + org-appear-autosubmarkers t) + (run-at-time nil nil #'org-appear--set-elements)) #+end_src Similarly, LaTeX fragments previews are nice and all, but if I have my cursor on it, I want to see the LaTeX source code and modify it, not just the generated image! #+begin_src emacs-lisp - (use-package org-fragtog - :defer t - :after org - :straight (:build t) - :hook (org-mode . org-fragtog-mode)) +(use-package org-fragtog + :defer t + :after org + :straight (:build t) + :hook (org-mode . org-fragtog-mode)) #+end_src Tired of seeing lots of actual stars ~*~ in your headers, and you want a @@ -3695,50 +3702,50 @@ found out how out-of-date and abandoned it is? (Last commit was on September 18th, 2014… damn…) Search no more, ~org-superstar~ will take care of that for you! #+begin_src emacs-lisp - (use-package org-superstar - :after org - :straight (:build t) - :hook (org-mode . org-superstar-mode) - :config - (setq org-superstar-leading-bullet ?\s - org-superstar-leading-fallback ?\s - org-hide-leading-stars nil - org-superstar-todo-bullet-alist - '(("TODO" . 9744) - ("[ ]" . 9744) - ("DONE" . 9745) - ("[X]" . 9745)))) +(use-package org-superstar + :after org + :straight (:build t) + :hook (org-mode . org-superstar-mode) + :config + (setq org-superstar-leading-bullet ?\s + org-superstar-leading-fallback ?\s + org-hide-leading-stars nil + org-superstar-todo-bullet-alist + '(("TODO" . 9744) + ("[ ]" . 9744) + ("DONE" . 9745) + ("[X]" . 9745)))) #+end_src ~org-fancy-priorities~ change the priority of an org element such such as ~#A~ to anything user-defined. Let’s make this anything all-the-icons icons! #+begin_src emacs-lisp - (use-package org-fancy-priorities - :after (org all-the-icons) - :straight (:build t) - :hook (org-mode . org-fancy-priorities-mode) - :hook (org-agenda-mode . org-fancy-priorities-mode) - :config - (setq org-fancy-priorities-list `(,(all-the-icons-faicon "flag" :height 1.1 :v-adjust 0.0) - ,(all-the-icons-faicon "arrow-up" :height 1.1 :v-adjust 0.0) - ,(all-the-icons-faicon "square" :height 1.1 :v-adjust 0.0)))) +(use-package org-fancy-priorities + :after (org all-the-icons) + :straight (:build t) + :hook (org-mode . org-fancy-priorities-mode) + :hook (org-agenda-mode . org-fancy-priorities-mode) + :config + (setq org-fancy-priorities-list `(,(all-the-icons-faicon "flag" :height 1.1 :v-adjust 0.0) + ,(all-the-icons-faicon "arrow-up" :height 1.1 :v-adjust 0.0) + ,(all-the-icons-faicon "square" :height 1.1 :v-adjust 0.0)))) #+end_src /Org Outline Tree/ is a better way of managing my org files’ outline. #+begin_src emacs-lisp - (use-package org-ol-tree - :defer t - :after org - :straight (org-ol-tree :build t - :host github - :type git - :repo "Townk/org-ol-tree") - :general - (:keymaps 'org-mode-map - :states 'normal - :prefix "," - "O" #'org-ol-tree)) +(use-package org-ol-tree + :defer t + :after org + :straight (org-ol-tree :build t + :host github + :type git + :repo "Townk/org-ol-tree") + :general + (:keymaps 'org-mode-map + :states 'normal + :prefix "," + "O" #'org-ol-tree)) #+end_src *** Misc @@ -3747,27 +3754,27 @@ icons! :END: ~org-tree-slide~ is a presentation tool for org-mode. #+begin_src emacs-lisp - (use-package org-tree-slide - :defer t - :after org - :straight (:build t) - :init - (general-define-key - :keymaps 'org-mode-map - :states 'normal - "" #'org-tree-slide-mode) - :config - (setq org-tree-slide-skip-done nil) - (general-define-key - :keymaps 'org-tree-slide-mode-map - :states 'normal - :prefix "," - "d" (lambda () (interactive (setq org-tree-slide-skip-done (not org-tree-slide-skip-done)))) - "p" #'org-tree-slide-move-next-tree - "n" #'org-tree-slide-move-previous-tree - "t" #'org-tree-slide-move-next-tree - "s" #'org-tree-slide-move-previous-tree - "u" #'org-tree-slide-content)) +(use-package org-tree-slide + :defer t + :after org + :straight (:build t) + :init + (general-define-key + :keymaps 'org-mode-map + :states 'normal + "" #'org-tree-slide-mode) + :config + (setq org-tree-slide-skip-done nil) + (general-define-key + :keymaps 'org-tree-slide-mode-map + :states 'normal + :prefix "," + "d" (lambda () (interactive (setq org-tree-slide-skip-done (not org-tree-slide-skip-done)))) + "p" #'org-tree-slide-move-next-tree + "n" #'org-tree-slide-move-previous-tree + "t" #'org-tree-slide-move-next-tree + "s" #'org-tree-slide-move-previous-tree + "u" #'org-tree-slide-content)) #+end_src ** Programming languages @@ -3783,47 +3790,47 @@ icons! :CUSTOM_ID: Packages-Configuration-Programming-languages-Flycheckb446fl6184j0 :END: #+begin_src emacs-lisp - (use-package flycheck - :straight (:build t) - :defer t - :init - (global-flycheck-mode) - :config - (setq flycheck-emacs-lisp-load-path 'inherit) +(use-package flycheck + :straight (:build t) + :defer t + :init + (global-flycheck-mode) + :config + (setq flycheck-emacs-lisp-load-path 'inherit) - ;; Rerunning checks on every newline is a mote excessive. - (delq 'new-line flycheck-check-syntax-automatically) - ;; And don’t recheck on idle as often - (setq flycheck-idle-change-delay 2.0) + ;; Rerunning checks on every newline is a mote excessive. + (delq 'new-line flycheck-check-syntax-automatically) + ;; And don’t recheck on idle as often + (setq flycheck-idle-change-delay 2.0) - ;; For the above functionality, check syntax in a buffer that you - ;; switched to on briefly. This allows “refreshing” the syntax check - ;; state for several buffers quickly after e.g. changing a config - ;; file. - (setq flycheck-buffer-switch-check-intermediate-buffers t) + ;; For the above functionality, check syntax in a buffer that you + ;; switched to on briefly. This allows “refreshing” the syntax check + ;; state for several buffers quickly after e.g. changing a config + ;; file. + (setq flycheck-buffer-switch-check-intermediate-buffers t) - ;; Display errors a little quicker (default is 0.9s) - (setq flycheck-display-errors-delay 0.2)) + ;; Display errors a little quicker (default is 0.9s) + (setq flycheck-display-errors-delay 0.2)) - (use-package flycheck-popup-tip - :straight (:build t) - :after flycheck - :hook (flycheck-mode . flycheck-popup-tip-mode) - :config - (setq flycheck-popup-tip-error-prefix "X ") - (after! evil - (add-hook 'evil-insert-state-entry-hook - #'flycheck-popup-tip-delete-popup) - (add-hook 'evil-replace-state-entry-hook - #'flycheck-popup-tip-delete-popup))) +(use-package flycheck-popup-tip + :straight (:build t) + :after flycheck + :hook (flycheck-mode . flycheck-popup-tip-mode) + :config + (setq flycheck-popup-tip-error-prefix "X ") + (after! evil + (add-hook 'evil-insert-state-entry-hook + #'flycheck-popup-tip-delete-popup) + (add-hook 'evil-replace-state-entry-hook + #'flycheck-popup-tip-delete-popup))) - (use-package flycheck-posframe - :straight (:build t) - :hook (flycheck-mode . flycheck-posframe-mode) - :config - (setq flycheck-posframe-warning-prefix "! " - flycheck-posframe-info-prefix "··· " - flycheck-posframe-error-prefix "X ")) +(use-package flycheck-posframe + :straight (:build t) + :hook (flycheck-mode . flycheck-posframe-mode) + :config + (setq flycheck-posframe-warning-prefix "! " + flycheck-posframe-info-prefix "··· " + flycheck-posframe-error-prefix "X ")) #+end_src **** LSP-Mode @@ -3834,110 +3841,110 @@ icons! Protocol]] and offers Emacs an IDE-like experience. In short, it’s awesome! #+begin_src emacs-lisp - (use-package lsp-mode - :defer t - :straight (:build t) - :init - (setq lsp-keymap-prefix "C-c l") - ;; (dolist (hook '(rust-mode-hook - ;; c-mode-hook - ;; c++-mode-hook - ;; css-mode-hook - ;; html-mode-hook - ;; lua-mode-hook - ;; rust-mode-hook - ;; dockerfile-mode-hook)) - ;; (add-hook hook #'lsp-deferred)) +(use-package lsp-mode + :defer t + :straight (:build t) + :init + (setq lsp-keymap-prefix "C-c l") + ;; (dolist (hook '(rust-mode-hook + ;; c-mode-hook + ;; c++-mode-hook + ;; css-mode-hook + ;; html-mode-hook + ;; lua-mode-hook + ;; rust-mode-hook + ;; dockerfile-mode-hook)) + ;; (add-hook hook #'lsp-deferred)) - ;; (dolist (mode '(#'lsp-enable-which-key-integration - ;; #'lsp-ui-mode)) - ;; (add-hook 'lsp-mode-hook mode)) - :hook ((rust-mode . lsp-deferred) - (c-mode . lsp-deferred) - (c++-mode . lsp-deferred) - (css-mode . lsp-deferred) - (dart-mode . lsp-deferred) - (html-mode . lsp-deferred) - (lua-mode . lsp-deferred) - (rust-mode . lsp-deferred) - (dockerfile-mode . lsp-deferred) - (lsp-mode . lsp-enable-which-key-integration) - (lsp-mode . lsp-ui-mode)) - :commands (lsp lsp-deferred) - :custom - (lsp-rust-analyzer-cargo-watch-command "clippy") - (lsp-eldoc-render-all t) - (lsp-idle-delay 0.6) - (lsp-rust-analyzer-server-display-inlay-hints t)) + ;; (dolist (mode '(#'lsp-enable-which-key-integration + ;; #'lsp-ui-mode)) + ;; (add-hook 'lsp-mode-hook mode)) + :hook ((rust-mode . lsp-deferred) + (c-mode . lsp-deferred) + (c++-mode . lsp-deferred) + (css-mode . lsp-deferred) + (dart-mode . lsp-deferred) + (html-mode . lsp-deferred) + (lua-mode . lsp-deferred) + (rust-mode . lsp-deferred) + (dockerfile-mode . lsp-deferred) + (lsp-mode . lsp-enable-which-key-integration) + (lsp-mode . lsp-ui-mode)) + :commands (lsp lsp-deferred) + :custom + (lsp-rust-analyzer-cargo-watch-command "clippy") + (lsp-eldoc-render-all t) + (lsp-idle-delay 0.6) + (lsp-rust-analyzer-server-display-inlay-hints t)) #+end_src I also want all the visual enhancements LSP can provide. #+begin_src emacs-lisp - (use-package lsp-ui - :after lsp - :defer t - :straight (:build t) - :commands lsp-ui-mode - :custom - (lsp-ui-peek-always-show t) - (lsp-ui-sideline-show-hover t) - (lsp-ui-doc-enable t) - :config - (general-define-key - :states 'normal - :keymaps 'lsp-ui-peek-mode-map - :prefix "," - "c" #'lsp-ui-pook--select-prev-file - "t" #'lsp-ui-pook--select-next - "s" #'lsp-ui-pook--select-prev - "r" #'lsp-ui-pook--select-next-file)) +(use-package lsp-ui + :after lsp + :defer t + :straight (:build t) + :commands lsp-ui-mode + :custom + (lsp-ui-peek-always-show t) + (lsp-ui-sideline-show-hover t) + (lsp-ui-doc-enable t) + :config + (general-define-key + :states 'normal + :keymaps 'lsp-ui-peek-mode-map + :prefix "," + "c" #'lsp-ui-pook--select-prev-file + "t" #'lsp-ui-pook--select-next + "s" #'lsp-ui-pook--select-prev + "r" #'lsp-ui-pook--select-next-file)) #+end_src And let’s enable some intergration with ~ivy~. #+begin_src emacs-lisp - (use-package lsp-ivy - :straight (:build t) - :defer t - :after lsp - :commands lsp-ivy-workspace-symbol) +(use-package lsp-ivy + :straight (:build t) + :defer t + :after lsp + :commands lsp-ivy-workspace-symbol) #+end_src #+begin_src emacs-lisp - (use-package lsp-treemacs - :defer t - :straight (:build t) - :requires treemacs) +(use-package lsp-treemacs + :defer t + :straight (:build t) + :requires treemacs) #+end_src #+begin_src emacs-lisp - (use-package exec-path-from-shell - :defer t - :straight (:build t) - :init (exec-path-from-shell-initialize)) +(use-package exec-path-from-shell + :defer t + :straight (:build t) + :init (exec-path-from-shell-initialize)) #+end_src ~dap-mode~ is an advanced debugging mode that works through lsp. #+begin_src emacs-lisp - (use-package dap-mode - :after lsp - :defer t - :straight (:build t) - :config - (dap-ui-mode) - (dap-ui-controls-mode 1) +(use-package dap-mode + :after lsp + :defer t + :straight (:build t) + :config + (dap-ui-mode) + (dap-ui-controls-mode 1) - (require 'dap-lldb) - (require 'dap-gdb-lldb) + (require 'dap-lldb) + (require 'dap-gdb-lldb) - (dap-gdb-lldb-setup) - (dap-register-debug-template - "Rust::LLDB Run Configuration" - (list :type "lldb" - :request "launch" - :name "LLDB::Run" - :gdbpath "rust-lldb" - :target nil - :cwd nil))) + (dap-gdb-lldb-setup) + (dap-register-debug-template + "Rust::LLDB Run Configuration" + (list :type "lldb" + :request "launch" + :name "LLDB::Run" + :gdbpath "rust-lldb" + :target nil + :cwd nil))) #+end_src *** DSLs @@ -3960,11 +3967,11 @@ Letsencrypt! Automatic HTTPS, what more do you want? All that is nice and all, but Emacs doesn’t support the syntax of Caddy files natively, so let’s install ~caddyfile-mode~: #+begin_src emacs-lisp - (use-package caddyfile-mode - :defer t - :straight (:build t) - :mode (("Caddyfile\\'" . caddyfile-mode) - ("caddy\\.conf\\'" . caddyfile-mode))) +(use-package caddyfile-mode + :defer t + :straight (:build t) + :mode (("Caddyfile\\'" . caddyfile-mode) + ("caddy\\.conf\\'" . caddyfile-mode))) #+end_src **** CMake @@ -3976,36 +3983,36 @@ be built. It is not as standard as some other tools such as automake, autoconfig, and the likes, but still pretty standard. CMake however doesn’t have a major mode available by default, so let’s provide one. #+begin_src emacs-lisp - (use-package cmake-mode - :defer t - :straight (:build t)) +(use-package cmake-mode + :defer t + :straight (:build t)) #+end_src Let’s enable first some autocompletion for it. #+begin_src emacs-lisp - (use-package company-cmake - :straight (company-cmake :build t - :type git - :host github - :repo "purcell/company-cmake") - :after cmake-mode - :defer t) +(use-package company-cmake + :straight (company-cmake :build t + :type git + :host github + :repo "purcell/company-cmake") + :after cmake-mode + :defer t) #+end_src And let’s also enable a more advanced CMake fontlock. #+begin_src emacs-lisp - (use-package cmake-font-lock - :defer t - :after cmake-mode - :straight (:build t)) +(use-package cmake-font-lock + :defer t + :after cmake-mode + :straight (:build t)) #+end_src And finally, let’s enable some Eldoc integration for CMake. #+begin_src emacs-lisp - (use-package eldoc-cmake - :straight (:build t) - :defer t - :after cmake-mode) +(use-package eldoc-cmake + :straight (:build t) + :defer t + :after cmake-mode) #+end_src **** Gnuplot @@ -4015,9 +4022,9 @@ And finally, let’s enable some Eldoc integration for CMake. This package is a front-end and major mode for the programming language [[http://www.gnuplot.info/][Gnuplot]]. Let’s make some beautiful graphs, shall we? #+begin_src emacs-lisp - (use-package gnuplot - :straight (:build t) - :defer t) +(use-package gnuplot + :straight (:build t) + :defer t) #+end_src **** Graphviz @@ -4027,11 +4034,11 @@ language [[http://www.gnuplot.info/][Gnuplot]]. Let’s make some beautiful grap [[https://graphviz.org/][Graphviz]], often known with ~dot~, allows to programatically create visual graphs and networks. #+begin_src emacs-lisp - (use-package graphviz-dot-mode - :straight (:build t) - :defer t - :config - (setq graphviz-dot-indent-width 4)) +(use-package graphviz-dot-mode + :straight (:build t) + :defer t + :config + (setq graphviz-dot-indent-width 4)) #+end_src **** Nginx @@ -4043,20 +4050,20 @@ of packages are required in order to be able to properly work with Nginx configuration files. First, we need the correct mode for editing Nginx configuration files. #+begin_src emacs-lisp - (use-package nginx-mode - :straight (:build t) - :defer t) +(use-package nginx-mode + :straight (:build t) + :defer t) #+end_src We then also have an autocompletion package that adds to ~company~ the Nginx syntax. #+begin_src emacs-lisp - (use-package company-nginx - :straight (:build t) - :defer t - :config - (add-hook 'nginx-mode-hook (lambda () - (add-to-list 'company-backends #'company-nginx)))) +(use-package company-nginx + :straight (:build t) + :defer t + :config + (add-hook 'nginx-mode-hook (lambda () + (add-to-list 'company-backends #'company-nginx)))) #+end_src **** Shells @@ -4066,9 +4073,9 @@ Nginx syntax. Aside from Eshell, my main shell on my machine is fish (see my [[file:fish.org][fish config]]), therefore I need a mode for it. #+begin_src emacs-lisp - (use-package fish-mode - :straight (:build t) - :defer t) +(use-package fish-mode + :straight (:build t) + :defer t) #+end_src **** Toml @@ -4076,10 +4083,10 @@ config]]), therefore I need a mode for it. :CUSTOM_ID: Packages-Configuration-Programming-languages-DSLs-Toml-txu8xvk0k4j0 :END: #+begin_src emacs-lisp - (use-package toml-mode - :straight (:build t) - :defer t - :mode "/\\(Cargo.lock\\|\\.cargo/config\\)\\'") +(use-package toml-mode + :straight (:build t) + :defer t + :mode "/\\(Cargo.lock\\|\\.cargo/config\\)\\'") #+end_src **** Yaml diff --git a/org/config/fish.org b/org/config/fish.org index 00c2a2b..1a44f39 100644 --- a/org/config/fish.org +++ b/org/config/fish.org @@ -18,9 +18,9 @@ abbreviations. Just in case, we might need sometimes to declare the fish function =fish_title= as =true=, so let’s do so. #+BEGIN_SRC fish - function fish_title - true - end +function fish_title + true +end #+END_SRC * Fish from within Emacs @@ -30,9 +30,9 @@ as =true=, so let’s do so. I sometimes call fish from within emacs, with =M-x ansi-term=. In this case, the variable =TERM= needs to have the value =eterm-color=. #+BEGIN_SRC fish - if test -n "$EMACS" - set -x TERM eterm-color - end +if test -n "$EMACS" + set -x TERM eterm-color +end #+END_SRC * Tramp remote access @@ -44,14 +44,14 @@ precise shell appearance: a simple =$= followed by a space after which to put the commands it needs to execute, and nothing else. Due to this, let’s deactivate and redefine some of the functions defining the appearance of fish. #+BEGIN_SRC fish - if test "$TERM" = "dumb" - function fish_prompt - echo "\$ " - end - function fish_right_prompt; end - function fish_greeting; end - function fish_title; end - end +if test "$TERM" = "dumb" + function fish_prompt + echo "\$ " + end + function fish_right_prompt; end + function fish_greeting; end + function fish_title; end +end #+END_SRC * Regular fish shell appearance @@ -63,88 +63,88 @@ when I’m the one using it: the ~fish_greeting~ function. I use it to give me a overview of my computer’s status, including its hostname, uptime, disks usage, ram usage, swap usage, and networking. #+BEGIN_SRC fish - set RED '\033[0;31m' - set GREEN '\033[0;32m' - set NC '\033[0m' +set RED '\033[0;31m' +set GREEN '\033[0;32m' +set NC '\033[0m' - function display_slider # used total - set -l slider_length 38 - set -l used $argv[1] - set -l total $argv[2] - set -l used_slider (math -s0 "($used * $slider_length) / $total") - set -l unused_slider (math -s0 "$slider_length - $used_slider") - echo -en "[" - echo -en $RED - echo -en (string repeat -n $used_slider '=') - echo -en $GREEN - echo -en (string repeat -n $unused_slider '=') - echo -en $NC - echo -en "]" - end +function display_slider # used total + set -l slider_length 38 + set -l used $argv[1] + set -l total $argv[2] + set -l used_slider (math -s0 "($used * $slider_length) / $total") + set -l unused_slider (math -s0 "$slider_length - $used_slider") + echo -en "[" + echo -en $RED + echo -en (string repeat -n $used_slider '=') + echo -en $GREEN + echo -en (string repeat -n $unused_slider '=') + echo -en $NC + echo -en "]" +end - function fish_greeting - set -l ruler_length 79 - set -l ruler (string repeat -n $ruler_length "=") +function fish_greeting + set -l ruler_length 79 + set -l ruler (string repeat -n $ruler_length "=") - set -l osname (cat /etc/os-release | grep -i pretty_name | sed 's/.*"\(.*\)".*/\1/') - set -l uptime (uptime -p | sed 's/up //') + set -l osname (cat /etc/os-release | grep -i pretty_name | sed 's/.*"\(.*\)".*/\1/') + set -l uptime (uptime -p | sed 's/up //') - set -l root (df -Ph | grep -E "/\$") - set -l root_p (echo $root | awk '{print $5}' | tr -d '%') - set -l root_used (echo $root | awk '{print $3}') - set -l root_total (echo $root | awk '{print $2}') + set -l root (df -Ph | grep -E "/\$") + set -l root_p (echo $root | awk '{print $5}' | tr -d '%') + set -l root_used (echo $root | awk '{print $3}') + set -l root_total (echo $root | awk '{print $2}') - set -l ram (free -tm | grep Mem) - set -l ram_total (echo $ram | awk '{print $2}') - set -l ram_used (echo $ram | awk '{print $3}') - set -l ram_p (math -s0 "$ram_used / $ram_total * 100") + set -l ram (free -tm | grep Mem) + set -l ram_total (echo $ram | awk '{print $2}') + set -l ram_used (echo $ram | awk '{print $3}') + set -l ram_p (math -s0 "$ram_used / $ram_total * 100") - set -l swap (free -tm | grep Swap) - set -l swap_total (echo $swap | awk '{print $2}') - set -l swap_used (echo $swap | awk '{print $3}') - set -l swap_p (math -s0 "$swap_used / $swap_total * 100") + set -l swap (free -tm | grep Swap) + set -l swap_total (echo $swap | awk '{print $2}') + set -l swap_used (echo $swap | awk '{print $3}') + set -l swap_p (math -s0 "$swap_used / $swap_total * 100") - set -l connections (nmcli c s | grep -E "wifi|ethernet" | grep -v '\-\-') - set -l wifi (echo $connections | grep "wifi" | awk '{print $1}') - set -l ethernet (test "$connections" = "*ethernet*" && echo -e $GREEN"UP"$NC || echo -e $RED"DOWN"$NC) - set -l wifi (test -n wifi && echo -e $GREEN$wifi$NC || echo - $RED"DOWN"$NC) + set -l connections (nmcli c s | grep -E "wifi|ethernet" | grep -v '\-\-') + set -l wifi (echo $connections | grep "wifi" | awk '{print $1}') + set -l ethernet (test "$connections" = "*ethernet*" && echo -e $GREEN"UP"$NC || echo -e $RED"DOWN"$NC) + set -l wifi (test -n wifi && echo -e $GREEN$wifi$NC || echo - $RED"DOWN"$NC) - echo $ruler - printf "OS......: %-30sKernel: %s %s\n" $osname (uname -s) (uname -r) - printf "Hostname: %-30sUptime: %s\n" (hostname) $uptime - printf "Ethernet: %-41sWifi..: %s\n" $ethernet $wifi - printf "Disks...: %-6s %s %6s / %6s (%2d%%)\n" "/" (display_slider $root_p 100) $root_used $root_total $root_p + echo $ruler + printf "OS......: %-30sKernel: %s %s\n" $osname (uname -s) (uname -r) + printf "Hostname: %-30sUptime: %s\n" (hostname) $uptime + printf "Ethernet: %-41sWifi..: %s\n" $ethernet $wifi + printf "Disks...: %-6s %s %6s / %6s (%2d%%)\n" "/" (display_slider $root_p 100) $root_used $root_total $root_p - # loop other mountpoints - for mp in (df -Ph 2> /dev/null | egrep "sd|tank|nvme" | egrep -v "boot|/\$") - set -l mp_p (echo $mp | awk '{print $5}' | tr -d '%') - set -l mp_used (echo $mp | awk '{print $3}') - set -l mp_total (echo $mp | awk '{print $2}') - set -l mp_name (echo $mp | awk '{print $6}') - printf " %-6s %s %6s / %6s (%2d%%)\n" $mp_name (display_slider $mp_p 100) $mp_used $mp_total $mp_p - end + # loop other mountpoints + for mp in (df -Ph 2> /dev/null | egrep "sd|tank|nvme" | egrep -v "boot|/\$") + set -l mp_p (echo $mp | awk '{print $5}' | tr -d '%') + set -l mp_used (echo $mp | awk '{print $3}') + set -l mp_total (echo $mp | awk '{print $2}') + set -l mp_name (echo $mp | awk '{print $6}') + printf " %-6s %s %6s / %6s (%2d%%)\n" $mp_name (display_slider $mp_p 100) $mp_used $mp_total $mp_p + end - printf "Ram.....: %s %5dM / %5dM (%2d%%)\n" (display_slider $ram_used $ram_total) $ram_used $ram_total $ram_p - printf "Swap....: %s %5dM / %5dM (%2d%%)\n" (display_slider $swap_used $swap_total) $swap_used $swap_total $swap_p - echo $ruler - end + printf "Ram.....: %s %5dM / %5dM (%2d%%)\n" (display_slider $ram_used $ram_total) $ram_used $ram_total $ram_p + printf "Swap....: %s %5dM / %5dM (%2d%%)\n" (display_slider $swap_used $swap_total) $swap_used $swap_total $swap_p + echo $ruler +end #+END_SRC The theme I use for fish is [[https://github.com/oh-my-fish/theme-bobthefish][bobthefish]], which by default puts a really long timestamp to the right of the prompt. I want something shorter, so here is the variable to set, using the format specified in ~date(1)~. #+BEGIN_SRC fish - set -g theme_date_format "+%g-%m-%d %H:%M:%S" +set -g theme_date_format "+%g-%m-%d %H:%M:%S" #+END_SRC I also wish to have a kinda different newline prompt, so let’s set it: #+BEGIN_SRC fish - set -g theme_newline_prompt 'λ ' +set -g theme_newline_prompt 'λ ' #+END_SRC Finally, let’s set our prompt’s theme to the Nord theme. #+BEGIN_SRC fish - set -g theme_color_scheme nord +set -g theme_color_scheme nord #+END_SRC * Global variables @@ -154,24 +154,24 @@ Finally, let’s set our prompt’s theme to the Nord theme. In order to keep some other code clean, I set the ~$BROWSER~ variable so I don’t have to call my web browser directly but rather with this variable. #+BEGIN_SRC fish - set -gx BROWSER firefox +set -gx BROWSER firefox #+END_SRC Sometimes, software will rely on =SUDO_ASKPASS= to get a GUI from which it can get the sudo password. So, let’s declare it. #+BEGIN_SRC fish - set -gx SUDO_ASKPASS ~/.local/bin/askpass +set -gx SUDO_ASKPASS ~/.local/bin/askpass #+END_SRC In general, I prefer using ~bat~ to ~less~, although the former relies on the latter, but ~bat~ provides nice wrapping around ~less~, including syntax highlighting. Let’s set the manpager to bat then: #+BEGIN_SRC fish - set -x MANPAGER "sh -c 'col -bx | bat -l man -p'" +set -x MANPAGER "sh -c 'col -bx | bat -l man -p'" #+END_SRC #+begin_src fish - set -x XMODIFIERS +set -x XMODIFIERS #+end_src ** Development @@ -182,8 +182,8 @@ Now, let’s declare our editor of choice, EmacsClient; not Emacs itself since i will most often be just quick edits, nothing too heavy, if it is called from the ~EDITOR~ variable (from Git, for example), or from the ~VISUAL~ variable. #+BEGIN_SRC fish - set -gx EDITOR emacsclient -c - set -gx VISUAL emacsclient -c +set -gx EDITOR emacsclient -c +set -gx VISUAL emacsclient -c #+END_SRC We also need to set the path to the Dart SDK. @@ -198,21 +198,21 @@ set -gx ANDROID_HOME $HOME/Android/Sdk Still related to Dart and Flutter development, #+BEGIN_SRC fish - set -gx CHROME_EXECUTABLE /usr/bin/chromium +set -gx CHROME_EXECUTABLE /usr/bin/chromium #+END_SRC Next, we have two variables from Deno, the Node.js destroyer. Its base directory will be set in my XDG config directory, and its binaries will be located in my local binaries directory (see below). #+BEGIN_SRC fish - set -gx DENO_DIR $HOME/.config/deno - set -gx DENO_INSTALL_ROOT $HOME/.local/bin/deno +set -gx DENO_DIR $HOME/.config/deno +set -gx DENO_INSTALL_ROOT $HOME/.local/bin/deno #+END_SRC Finally, some development packages require the =PKG_CONFIG_PATH= to be set, so let’s do so. #+BEGIN_SRC fish - set -gx PKG_CONFIG_PATH /usr/local/lib/pkgconfig/ $PKG_CONFIG_PATH +set -gx PKG_CONFIG_PATH /usr/local/lib/pkgconfig/ $PKG_CONFIG_PATH #+END_SRC ** ~$PATH~ @@ -237,8 +237,8 @@ my own executables, and some more. #+NAME: generate-extra-paths #+BEGIN_SRC emacs-lisp :var paths=extra-paths[,0] :exports none :cache yes - (mapconcat #'identity - paths " \\\n") +(mapconcat #'identity + paths " \\\n") #+END_SRC #+RESULTS[3fd24377f29513d4c7edcd9621d0462665efb403]: generate-extra-paths @@ -251,8 +251,8 @@ my own executables, and some more. So, let’s set our user paths: #+BEGIN_SRC fish :noweb yes - set -g fish_user_paths \ - <> +set -g fish_user_paths \ +<> #+END_SRC * Abbreviations @@ -261,12 +261,12 @@ So, let’s set our user paths: :END: #+NAME: generate-abbr #+BEGIN_SRC emacs-lisp :var table=[] :exports none :tangle no - (replace-regexp-in-string "\\\\vert[{}]*" - "|" - (mapconcat (lambda (x) (format "abbr %s '%s'" (car x) (cadr x))) - table - "\n") - t t) +(replace-regexp-in-string "\\\\vert[{}]*" + "|" + (mapconcat (lambda (x) (format "abbr %s '%s'" (car x) (cadr x))) + table + "\n") + t t) #+END_SRC Abbreviations are a great way to keep correctly track of which commands are run @@ -306,7 +306,7 @@ running right now, and =pscpu10= limits that to the top 10 threads. Similarly, | psmem10 | ps auxf \vert sort -nr -k 4 \vert head -10 | #+begin_SRC fish - <> +<> #+END_SRC ** System management (packages and services) @@ -332,7 +332,7 @@ can type =search=. Otherwise, if I want to include AUR results, I’ll use =paru | purge | paru -Sc | #+BEGIN_SRC fish - <> +<> #+END_SRC *** Service management @@ -349,7 +349,7 @@ system services, I can instead type a simple capital =S=. | suser | systemctl --user | #+BEGIN_SRC fish - <> +<> #+END_SRC ** Development @@ -373,7 +373,7 @@ configuration for debug or release profiles. Here is the corresponding fish configuration: #+BEGIN_SRC fish - <> +<> #+END_SRC *** Docker @@ -398,7 +398,7 @@ full command, so I use these instead. Here is the corresponding fish configuration: #+BEGIN_SRC fish - <> +<> #+END_SRC *** Text editors @@ -419,7 +419,7 @@ In case we want to launch Emacs in GUI mode anyways, ~egui~ is available too. Here is the corresponding fish configuration: #+BEGIN_SRC fish :noweb yes - <> +<> #+END_SRC *** Compilation @@ -438,7 +438,7 @@ with the ~-Wall~ flag activated. Here is the corresponding fish configuration: #+BEGIN_SRC fish - <> +<> #+END_SRC *** Git @@ -455,7 +455,7 @@ covered. Here is the corresponding fish configuration: #+BEGIN_SRC fish - <> +<> #+END_SRC ** LaTeX @@ -475,7 +475,7 @@ abbreviation. Same goes for ~texhash~ which must be run as sudo. Here is the corresponding fish configuration: #+BEGIN_SRC fish - <> +<> #+END_SRC ** Some security measures @@ -507,7 +507,7 @@ accidentally removing the root folder. I added the same option to =chgrp=, Here is the corresponding fish configuration: #+BEGIN_SRC fish - <> +<> #+END_SRC ** Typos @@ -530,7 +530,7 @@ So, let's just replace the former by the latter. I'm also very bad at typing Here is the corresponding fish configuration: #+BEGIN_SRC fish - <> +<> #+END_SRC ** Misc @@ -548,33 +548,33 @@ Here you will find various commands related to media in general. the first one is a command to play some chillhop from the [[https://www.youtube.com/user/Chillhopdotcom][Chillhop YouTube channel]]'s livestream. #+BEGIN_SRC fish - abbr chill 'mpv --force-window=no --no-video "https://www.youtube.com/user/Chillhopdotcom/live" &' +abbr chill 'mpv --force-window=no --no-video "https://www.youtube.com/user/Chillhopdotcom/live" &' #+END_SRC When it comes to mpv, I do not want to force it to open a graphical window if for example I want to listen to an audio file. I also do not want any border on that window. So, I declared this abbreviation. #+BEGIN_SRC fish - abbr mpv 'mpv --no-border --force-window=no' +abbr mpv 'mpv --no-border --force-window=no' #+END_SRC When I want to download a song from YouTube, I'll just use the command ~flac videoIdentifier~ to get it through ~youtube-dl~. #+BEGIN_SRC fish - abbr flac 'youtube-dl -x --audio-format flac --audio-quality 0 -o "~/Music/%(uploader)s/%(title)s.%(ext)s"' +abbr flac 'youtube-dl -x --audio-format flac --audio-quality 0 -o "~/Music/%(uploader)s/%(title)s.%(ext)s"' #+END_SRC Some sane default options for ~sxiv~, a simple X image Viewer. This includes playing GIFs and not displaying the filename below. Sxiv will also open in fullscreen and will fit the displayed image to the frame. #+BEGIN_SRC fish - abbr sxiv 'sxiv -abfs f' +abbr sxiv 'sxiv -abfs f' #+END_SRC Finally, let's declare the following abbreviation that will launch an mpv instance displaying my webcam: #+BEGIN_SRC fish - abbr webcam 'devour mpv --demuxer-lavf-format=video4linux2 --demuxer-lavf-o-set=input_format=mjpeg av://v4l2:/dev/video0' +abbr webcam 'devour mpv --demuxer-lavf-format=video4linux2 --demuxer-lavf-o-set=input_format=mjpeg av://v4l2:/dev/video0' #+END_SRC *** Sudo @@ -585,7 +585,7 @@ First, I make it so that ~sudo~ comes with the ~-A~ switch in order to call my custom graphical script for getting my password (see [[file:bin.org::#Askpass-d0d7a8c0][askpass]]). I also made it so ~please~ is an equivalent to ~sudo -A~ as a joke. #+BEGIN_SRC fish - abbr please 'sudo -A' +abbr please 'sudo -A' #+END_SRC *** History @@ -595,7 +595,7 @@ custom graphical script for getting my password (see [[file:bin.org::#Askpass-d0 I find it more intuitive and faster to just write ~hist~ instead of ~history~, so let's declare that. #+BEGIN_SRC fish - abbr hist history +abbr hist history #+END_SRC *** Compression @@ -614,7 +614,7 @@ management]]). | untar | tar -xvzf | #+BEGIN_SRC fish - <> +<> #+END_SRC *** exa @@ -628,7 +628,7 @@ management]]). | lsl | exa -halg@ --group-directories-first --git | #+BEGIN_SRC fish - <> +<> #+END_SRC *** Network Management @@ -638,7 +638,7 @@ management]]). First, we have just =nmcli= with sane default options, that is a pretty output with colors. #+BEGIN_SRC fish - abbr nmcli 'nmcli -p -c auto' +abbr nmcli 'nmcli -p -c auto' #+END_SRC *** NordVPN @@ -662,7 +662,7 @@ the US. | ncu | nordvpn c United_States | #+BEGIN_SRC fish - <> +<> #+END_SRC *** Wget @@ -671,7 +671,7 @@ the US. :END: By default, continue a download that was interupted. #+BEGIN_SRC fish - abbr wget 'wget -c' +abbr wget 'wget -c' #+END_SRC * Last thing before we’re done diff --git a/org/config/index.org b/org/config/index.org index 6c30194..09f46f6 100644 --- a/org/config/index.org +++ b/org/config/index.org @@ -126,23 +126,23 @@ This file is tangled at ~$HOME/.gtkrc-2.0~. This is an equivalent for the GTK3 configuration file you will see below, and it shares most of its settings. First, let’s select the Nordic theme for GTK2. Let’s also set the icon theme. #+BEGIN_SRC conf-unix - # -*- mode: unix-config -*- - gtk-theme-name="Nordic" - gtk-icon-theme-name="Flat-Remix-Dark" +# -*- mode: unix-config -*- +gtk-theme-name="Nordic" +gtk-icon-theme-name="Flat-Remix-Dark" #+END_SRC #+BEGIN_SRC conf-unix - gtk-xft-antialias=1 - gtk-xft-hinting=1 - gtk-xft-hintstyle="hintslight" +gtk-xft-antialias=1 +gtk-xft-hinting=1 +gtk-xft-hintstyle="hintslight" #+END_SRC This changes the shortcuts in menu, let’s also make the menus snappier. #+BEGIN_SRC conf-unix - gtk-can-change-accels=1 - gtk-menu-bar-popup-delay=0 - gtk-menu-popdown-delay=0 - gtk-menu-popup-delay=0 +gtk-can-change-accels=1 +gtk-menu-bar-popup-delay=0 +gtk-menu-popdown-delay=0 +gtk-menu-popup-delay=0 #+END_SRC ***** Filechooser @@ -151,60 +151,60 @@ This changes the shortcuts in menu, let’s also make the menus snappier. :CUSTOM_ID: Features-Graphical_tweaks-GTK_Settings-GTK2-Filechooser-389f040d :END: #+BEGIN_SRC conf-unix - [Filechooser Settings] +[Filechooser Settings] #+END_SRC The first option alows me to open the file chooser in the current working directory: #+BEGIN_SRC conf-unix - StartupMode=cwd +StartupMode=cwd #+END_SRC Next, setting the location mode to ~path-bar~ will show the path as buttons that can be clicked rather than the full path. #+BEGIN_SRC conf-unix - LocationMode=path-bar +LocationMode=path-bar #+END_SRC With this configuration, by default we won’t see hidden files. #+BEGIN_SRC conf-unix - ShowHidden=true +ShowHidden=true #+END_SRC And we'll also see the size of the visible files. #+BEGIN_SRC conf-unix - ShowSizeColumn=true +ShowSizeColumn=true #+END_SRC Now, let’s choose the geometry of our file picker. These two first lines set where the file picker appears: #+BEGIN_SRC conf-unix - GeometryX=566 - GeometryY=202 +GeometryX=566 +GeometryY=202 #+END_SRC And these two describe the size of the window: #+BEGIN_SRC conf-unix - GeometryWidth=800 - GeometryHeight=400 +GeometryWidth=800 +GeometryHeight=400 #+END_SRC With these two lines, we set how our files are sorted: by name, and in the ascending order. #+BEGIN_SRC conf-unix - SortColumn=name - SortOrder=ascending +SortColumn=name +SortOrder=ascending #+END_SRC Our default view mode is a list of files: #+BEGIN_SRC conf-unix - ViewMode=list-view +ViewMode=list-view #+END_SRC And finally, setting our icon view scale to ~-1~ sets the icon view to the max size. #+BEGIN_SRC conf-unix - IconViewScale=-1 +IconViewScale=-1 #+END_SRC **** GTK3 @@ -215,44 +215,44 @@ size. The following file helps me choosing the aspect of various GTK+ 3 software, including their theme and icons. First, let’s declare the header: #+BEGIN_SRC conf-unix - [Settings] +[Settings] #+END_SRC Now, let’s hint to GTK that I prefer dark themes. This can have an influence also on some websites that can detect this preference and therefore set their own theme to dark by themselves. #+BEGIN_SRC conf-unix - gtk-application-prefer-dark-theme = true +gtk-application-prefer-dark-theme = true #+END_SRC Next, the icon theme is the Flat Remix Dark icon theme: #+BEGIN_SRC conf-unix - gtk-icon-theme-name = Flat-Remix-Dark +gtk-icon-theme-name = Flat-Remix-Dark #+END_SRC Now, the general theme for GTK3 is Nordic. #+BEGIN_SRC conf-unix - gtk-theme-name = Nordic +gtk-theme-name = Nordic #+END_SRC #+BEGIN_SRC conf-unix - gtk-can-change-accels=1 - gtk-menu-bar-popup-delay=0 - gtk-menu-popdown-delay=0 - gtk-menu-popup-delay=0 +gtk-can-change-accels=1 +gtk-menu-bar-popup-delay=0 +gtk-menu-popdown-delay=0 +gtk-menu-popup-delay=0 #+END_SRC #+BEGIN_SRC conf-unix - gtk-xft-antialias=1 - gtk-xft-hinting=1 - gtk-xft-hintstyle=hintslight - # gtk-xft-rgba=rgb +gtk-xft-antialias=1 +gtk-xft-hinting=1 +gtk-xft-hintstyle=hintslight +# gtk-xft-rgba=rgb #+END_SRC Since window decorations are handled by my WMs, I will leave this variable empty. #+BEGIN_SRC conf-unix - gtk-decoration-layout= +gtk-decoration-layout= #+END_SRC *** Picom (Compton) @@ -271,45 +271,45 @@ You can find my Picom configuration [[file:picom.org][here]]. The main body in my Xresources declaration is the declaration of my color theme. It is based on the [[https://www.nordtheme.com/][Nord]] theme, from their [[https://github.com/arcticicestudio/nord-xresources/][Git repository]]. #+BEGIN_SRC conf - #define nord0 #2E3440 - #define nord1 #3B4252 - #define nord2 #434C5E - #define nord3 #4C566A - #define nord4 #D8DEE9 - #define nord5 #E5E9F0 - #define nord6 #ECEFF4 - #define nord7 #8FBCBB - #define nord8 #88C0D0 - #define nord9 #81A1C1 - #define nord10 #5E81AC - #define nord11 #BF616A - #define nord12 #D08770 - #define nord13 #EBCB8B - #define nord14 #A3BE8C - #define nord15 #B48EAD +#define nord0 #2E3440 +#define nord1 #3B4252 +#define nord2 #434C5E +#define nord3 #4C566A +#define nord4 #D8DEE9 +#define nord5 #E5E9F0 +#define nord6 #ECEFF4 +#define nord7 #8FBCBB +#define nord8 #88C0D0 +#define nord9 #81A1C1 +#define nord10 #5E81AC +#define nord11 #BF616A +#define nord12 #D08770 +#define nord13 #EBCB8B +#define nord14 #A3BE8C +#define nord15 #B48EAD - ,*.foreground: nord4 - ,*.background: nord0 - ,*.cursorColor: nord4 - ,*fading: 35 - ,*fadeColor: nord3 +,*.foreground: nord4 +,*.background: nord0 +,*.cursorColor: nord4 +,*fading: 35 +,*fadeColor: nord3 - ,*.color0: nord1 - ,*.color1: nord11 - ,*.color2: nord14 - ,*.color3: nord13 - ,*.color4: nord9 - ,*.color5: nord15 - ,*.color6: nord8 - ,*.color7: nord5 - ,*.color8: nord3 - ,*.color9: nord11 - ,*.color10: nord14 - ,*.color11: nord13 - ,*.color12: nord9 - ,*.color13: nord15 - ,*.color14: nord7 - ,*.color15: nord6 +,*.color0: nord1 +,*.color1: nord11 +,*.color2: nord14 +,*.color3: nord13 +,*.color4: nord9 +,*.color5: nord15 +,*.color6: nord8 +,*.color7: nord5 +,*.color8: nord3 +,*.color9: nord11 +,*.color10: nord14 +,*.color11: nord13 +,*.color12: nord9 +,*.color13: nord15 +,*.color14: nord7 +,*.color15: nord6 #+END_SRC ** Text and source code editing @@ -389,10 +389,10 @@ You can find my tmux configuration in [[file:tmux.org][tmux.org]]. It depends on :END: This file gets inserted automatically at the end of my emails. #+BEGIN_SRC text - Lucien “Phundrak” Cartier-Tilet - https://phundrak.com (Français) - https://phundrak.com/en (English) - Sent from GNU/Emacs +Lucien “Phundrak” Cartier-Tilet +https://phundrak.com (Français) +https://phundrak.com/en (English) +Sent from GNU/Emacs #+END_SRC *** Global gitignore @@ -405,14 +405,14 @@ of always adding them, let git now that some elements are to be ignored by default, hence the [[file:.gitignore_global][~/.gitignore_global]] file. First, we don’t want nano’s backup files. #+BEGIN_SRC text - ~* +~* #+END_SRC And object files and output binaries generated by =gcc= and the likes aren’t welcome either. #+BEGIN_SRC text - ,*.out - ,*.o +,*.out +,*.o #+END_SRC *** Paru @@ -428,19 +428,19 @@ is running, but if it ever happens it will be already concerning enough they managed to. I also make use of [[file:bin.org::#Emacs-stuff-Dired-2eeca9da][my custom script dired]] so I can use Emacs’ Dired as the file manager for ~paru~. #+BEGIN_SRC conf :tangle ~/.config/paru/paru.conf - [options] - BottomUp - Devel - DevelSuffixes = -git -cvs -svn -bzr -darcs -always - NewsOnUpgrade - PgpFetch - Provides - RemoveMake - SudoLoop - UpgradeMenu +[options] +BottomUp +Devel +DevelSuffixes = -git -cvs -svn -bzr -darcs -always +NewsOnUpgrade +PgpFetch +Provides +RemoveMake +SudoLoop +UpgradeMenu - [bin] - FileManager = dired +[bin] +FileManager = dired #+END_SRC * Installation diff --git a/org/config/neofetch.org b/org/config/neofetch.org index fbd8c0b..cdfab1e 100644 --- a/org/config/neofetch.org +++ b/org/config/neofetch.org @@ -26,9 +26,9 @@ The ~print_info~ function is the function called by Neofetch in order to print the system information it could fetch. In this function, we’ll choose what to display, and how. This function looks like this: #+BEGIN_SRC sh :tangle no - print_info() { - # Print information here… - } +print_info() { + # Print information here… +} #+END_SRC Generally, what we will display will be shown through the ~info~ function, @@ -58,16 +58,16 @@ interesting information; ~info "Memory" memory~ will look like #+NAME: info-elements-gen #+BEGIN_SRC emacs-lisp :var table=info-elements-table :cache yes - (mapconcat (lambda (x) - (let ((prefix (car x)) - (information (cadr x))) - (format "info %s%s" - (if (not (string= prefix "")) - (format "\"%s\" " prefix) - "") - information))) - table - "\n") +(mapconcat (lambda (x) + (let ((prefix (car x)) + (information (cadr x))) + (format "info %s%s" + (if (not (string= prefix "")) + (format "\"%s\" " prefix) + "") + information))) + table + "\n") #+END_SRC #+RESULTS[83eb4aaa554df955ad996157d911eec3a9251628]: info-elements-gen @@ -90,9 +90,9 @@ info "Memory" memory Hence, the function looks like so: #+BEGIN_SRC sh - print_info() { - <> - } +print_info() { + <> +} #+END_SRC Each of these modules can be tuned with the variables presented below. @@ -130,7 +130,7 @@ This variable can shorten the output of the ~distro~ function. - on :: ~Arch Linux~ - off :: ~Arch~ #+begin_src sh - distro_shorthand="off" +distro_shorthand="off" #+end_src It is possible to display when the distro has been installed on the computer. @@ -164,7 +164,7 @@ terminal emulator I use. - ~viu~ - flag :: ~--backend~ #+BEGIN_SRC sh - image_backend="kitty" +image_backend="kitty" #+END_SRC Now, since I indicated I wanted an image engine, I’ll indicate neofetch which @@ -182,7 +182,7 @@ image mode, your wallpaper will be used. - ~command output (neofetch --ascii "$(fortune | cowsay -W 30)")~ - Flag :: ~--source~ #+BEGIN_SRC sh - image_source="$HOME/org/config/img/leon.png" +image_source="$HOME/org/config/img/leon.png" #+END_SRC The default image size will probably not be correct since it is half the @@ -195,7 +195,7 @@ terminal width and I have an ultrawide monitor, so I’ll need to set it manuall - ~none~ - Flag :: ~--image-size~ or ~--size~ #+BEGIN_SRC sh - image_size="224px" +image_size="224px" #+END_SRC **** Kernel @@ -213,7 +213,7 @@ The variable below can shorten the output ofh the ~kernel~ function. - on :: ~4.8.9-1-ARCH~ - off :: ~Linux 4.8.9-1-ARCH~ #+begin_src sh - kernel_shorthand="off" +kernel_shorthand="off" #+end_src **** OS Architecture @@ -230,7 +230,7 @@ This variable can show or hide the OS architecture in the ~distro~ output. - on :: ~Arch Linux x86_64~ - off :: ~Arch Linux~ #+begin_src sh - os_arch="off" +os_arch="off" #+end_src **** Packages @@ -246,7 +246,7 @@ It is possible to show or hide Package Manager names. - tiny :: ~'908 (pacman, flatpak, snap)'~ - off :: ~'908'~ #+BEGIN_SRC sh - package_managers="on" +package_managers="on" #+END_SRC **** Shell @@ -284,7 +284,7 @@ This allows to show the shell’s version in the output of ~shell~. - on :: ~bash 4.4.5~ - off :: ~bash~ #+begin_src sh - shell_version="off" +shell_version="off" #+end_src *** Uptime @@ -304,7 +304,7 @@ it a bit, while ~tiny~ shortens it greatly. - off :: ~2 days, 10 hours, 3 minutes~ - tiny :: ~2d 10h 3m~ #+begin_src sh - uptime_shorthand="on" +uptime_shorthand="on" #+end_src *** IP address @@ -317,20 +317,20 @@ It is possible to display the machine’s public IP address with the function - Value :: ~"url"~ - Flag :: ~--ip_host~ #+begin_src sh - public_ip_host="http://ident.me" +public_ip_host="http://ident.me" #+end_src -- Default value :: ~""~ -- Values :: - - ~""~ - - ~""~ -- Flag :: ~""~ -- Supports :: -- Examples :: - - on :: ~~ - - off :: ~~ -#+begin_src sh -#+end_src +# - Default value :: ~""~ +# - Values :: +# - ~""~ +# - ~""~ +# - Flag :: ~""~ +# - Supports :: +# - Examples :: +# - on :: ~~ +# - off :: ~~ +# #+begin_src sh +# #+end_src *** Theming :PROPERTIES: @@ -354,7 +354,7 @@ With this value, it is possible to shorten the output of the computer’s themin - on :: ~Numix, Adwaita~ - off :: ~Numix [GTK2], Adwaita [GTK3]~ #+begin_src sh - gtk_shorthand="on" +gtk_shorthand="on" #+end_src **** Enable or disable theming display for GTK2 @@ -372,7 +372,7 @@ this variable. - on :: ~Numix [GTK2], Adwaita [GTK3]~ - off :: ~Adwaita [GTK3]~ #+begin_src sh - gtk2="off" +gtk2="off" #+end_src **** Enable or disable theming display for GTK3 @@ -389,7 +389,7 @@ The same variable as above is also available for GTK3. - on :: ~Numix [GTK2], Adwaita [GTK3]~ - off :: ~Numix [GTK2]~ #+begin_src sh - gtk3="off" +gtk3="off" #+end_src ** Hardware @@ -415,7 +415,7 @@ With this variables, it is possible to show or hide the brand of a CPU in the - on :: ~Intel i7-6500U~ - off :: ~i7-6500U~ #+begin_src sh - cpu_brand="off" +cpu_brand="off" #+end_src **** CPU speed @@ -432,7 +432,7 @@ With this variable, it is possible to show or hide the speed of the CPU. - on :: ~Intel i7-6500U (4) @ 3.1GHz~ - off :: ~Intel i7-6500U (4)~ #+begin_src sh - cpu_speed="off" +cpu_speed="off" #+end_src **** CPU speed type @@ -451,7 +451,7 @@ a value. - Flag :: ~--speed_type~ - Supports :: Linux with ~cpufreq~ #+begin_src sh - speed_type="bios_limit" +speed_type="bios_limit" #+end_src **** CPU speed shorthand @@ -469,7 +469,7 @@ supported in systems with CPU speed below 1GHz. - on :: ~i7-6500U (4) @ 3.1GHz~ - off :: ~i7-6500U (4) @ 3.100GHz~ #+begin_src sh - speed_shorthand="on" +speed_shorthand="on" #+end_src **** CPU cores @@ -490,7 +490,7 @@ available in the CPU. - physical :: ~Intel i7-6500U (2) @ 3.1GHz~ (All physical cores) - off :: ~Intel i7-6500U @ 3.1GHz~ #+begin_src sh - cpu_cores="off" +cpu_cores="off" #+end_src **** CPU temperature @@ -513,7 +513,7 @@ only supports newer Intel processors. - F :: ~Intel i7-6500U (4) @ 3.1GHz [82.0°F]~ - off :: ~Intel i7-6500U (4) @ 3.1GHz~ #+begin_src sh - cpu_temp="off" +cpu_temp="off" #+end_src *** GPU @@ -539,7 +539,7 @@ of ~gpu~. - on :: ~AMD HD 7950~ - off :: ~HD 7950~ #+begin_src sh - gpu_brand="off" +gpu_brand="off" #+end_src **** Which GPU to display @@ -557,14 +557,14 @@ This allows the user to choose which GPU appears in the output of the function - Supports :: Linux - Examples :: - all :: - #+BEGIN_SRC text - GPU1: AMD HD 7950 - GPU2: Intel Integrated Graphics - #+END_SRC +#+BEGIN_SRC text +GPU1: AMD HD 7950 +GPU2: Intel Integrated Graphics +#+END_SRC - dedicated :: ~GPU1: AMD HD 7950~ - integrated :: ~GPU1: Intel Integrated Graphics~ #+begin_src sh - gpu_type="all" +gpu_type="all" #+end_src *** Resolution @@ -583,5 +583,5 @@ individually. It is possible to display the refresh rate or to hide it. - on :: ~1920x1080 @ 60Hz~ - off :: ~1920x1080~ #+begin_src sh - refresh_rate="off" +refresh_rate="off" #+end_src diff --git a/org/config/picom.org b/org/config/picom.org index 564c87d..70af121 100644 --- a/org/config/picom.org +++ b/org/config/picom.org @@ -22,13 +22,13 @@ The following enables client-side shadows on windows. Note desktop windows (windows with ~_NET_WM_WINDOW_TYPE_DESKTOP~) never get shadow, unless explicitly requested using the wintypes option. #+BEGIN_SRC conf - shadow = true; +shadow = true; #+END_SRC The blur radius radius for shadows is measured in pixels, and it defaults to 12px. #+BEGIN_SRC conf - shadow-radius = 17; +shadow-radius = 17; #+END_SRC Picom can also apply some level of opacity on shadows. @@ -36,14 +36,14 @@ Picom can also apply some level of opacity on shadows. | Min value | ~0.0~ | | Max value | ~1.0~ | #+BEGIN_SRC conf - shadow-opacity = 0.6 +shadow-opacity = 0.6 #+END_SRC The left and top offsets for shadows are expressed in pixels. | Default value | ~-15~ | #+BEGIN_SRC conf - shadow-offset-x = -12; - shadow-offset-y = -12; +shadow-offset-x = -12; +shadow-offset-y = -12; #+END_SRC It is possible to set the color of the shadow with the string contained in @@ -51,39 +51,39 @@ It is possible to set the color of the shadow with the string contained in config, but this value will override any value in ~shadow-red~, ~shadow-green~, or ~shadow-blue~. #+BEGIN_SRC conf - shadow-color = "#000000" +shadow-color = "#000000" #+END_SRC It is possible to specify a list of conditions of windows that should have no shadow. | Default value | ~[]~ | #+BEGIN_SRC conf - shadow-exclude = [ - "name = 'Notification'", - "class_g = 'Conky'", - "class_g ?= 'Notify-osd'", - "class_g = 'Cairo-clock'", - "_GTK_FRAME_EXTENTS@:c" - ]; +shadow-exclude = [ + "name = 'Notification'", + "class_g = 'Conky'", + "class_g ?= 'Notify-osd'", + "class_g = 'Cairo-clock'", + "_GTK_FRAME_EXTENTS@:c" +]; #+END_SRC It is also possible to specify an X geometry that describes the region in which shadows should not be painted in, such as a dock window region. For example, #+BEGIN_SRC conf :tangle no - # shadow-exclude-reg = "x10+0+0" +# shadow-exclude-reg = "x10+0+0" #+END_SRC would make the 10 pixels at the bottom of the screen not have any shadow painted on. | Default value | ~""~ | #+BEGIN_SRC conf :tangle no - shadow-exclude-reg = "" +shadow-exclude-reg = "" #+END_SRC Finally, it is also possible to crop the shadow of a window fully on a particular Xinerama screen to the screen. - Default value :: ~false~ #+BEGIN_SRC conf - xinerama-shadow-crop = false +xinerama-shadow-crop = false #+END_SRC ** Deprecated options @@ -98,7 +98,7 @@ This option is deprecated, and users should use the ~wintypes~ option in their config file instead. | Default value | ~false~ | #+BEGIN_SRC conf - no-dock-shadow = false; +no-dock-shadow = false; #+END_SRC This option allows Picom not to draw on drag-and-drop windows. This option is @@ -106,7 +106,7 @@ deprecated, and users should use the ~wintypes~ option in their config file instead. | Default value | ~false~ | #+BEGIN_SRC conf - no-dnd-shadow = false; +no-dnd-shadow = false; #+END_SRC ~shadow-ignore-shaped~ is also deprecated. It used to indicate Picom not to @@ -114,15 +114,15 @@ paint shadows on shaped windows. Note shaped windows here means windows setting their shape through X Shape extension. Those using ARGB background are beyond Picom’s control. Since it is deprecated, you could instead use #+BEGIN_SRC conf :tangle no - shadow-exclude = 'bounding_shaped' +shadow-exclude = 'bounding_shaped' #+END_SRC or #+BEGIN_SRC conf :tangle no - shadow-exclude = 'bounding_shaped && !rounded_corners' +shadow-exclude = 'bounding_shaped && !rounded_corners' #+END_SRC | Default value | ~""~ | #+BEGIN_SRC conf :tangle no - shadow-ignore-shaped = "" +shadow-ignore-shaped = "" #+END_SRC * Rounded corners @@ -131,15 +131,15 @@ or :END: Here we can see the declaration of the corners’ radius: #+BEGIN_SRC conf - corner-radius = 9.0; +corner-radius = 9.0; #+END_SRC It is also possible to exclude some windows from getting their corners rounded. I personally excluded any window generated by AwesomeWM. #+BEGIN_SRC conf - rounded-corners-exclude = [ - "_NET_WM_WINDOW_TYPE@[0]:a = '_NET_WM_WINDOW_TYPE_DOCK'" - ]; +rounded-corners-exclude = [ + "_NET_WM_WINDOW_TYPE@[0]:a = '_NET_WM_WINDOW_TYPE_DOCK'" +]; #+END_SRC * Fading @@ -152,7 +152,7 @@ feature on or off. However, its behavior can be changed with ~no-fading-openclose~. | Default value | ~false~ | #+BEGIN_SRC conf - fading = true +fading = true #+END_SRC These values controls the opacity change between steps while fading in and out. @@ -160,35 +160,35 @@ These values controls the opacity change between steps while fading in and out. | Min value | ~0.01~ | | Max value | ~1.0~ | #+BEGIN_SRC conf - fade-in-step = 0.09; - fade-out-step = 0.08; +fade-in-step = 0.09; +fade-out-step = 0.08; #+END_SRC This value represents the time between steps in fade steps, in milliseconds. | Default value | ~10~ | | Min value | ~1~ | #+BEGIN_SRC conf - fade-delta = 20; +fade-delta = 20; #+END_SRC It is possible to exclude some windows that should not be faded with a specified list of conditions. | Default value | ~[]~ | #+BEGIN_SRC conf - fade-exclude = [ "class_g = 'mpv'" ]; +fade-exclude = [ "class_g = 'mpv'" ]; #+END_SRC This option allows Picom not to create any fade on windows opening or closing. | Default value | ~false~ | #+BEGIN_SRC conf - no-fading-openclose = true; +no-fading-openclose = true; #+END_SRC Finally, this option is a workaround for Openbox, Fluxbox and others by not fading destroyed ARGB windows with WM frame. | Default value | ~false~ | #+BEGIN_SRC conf - no-fading-destroyed-argb = false +no-fading-destroyed-argb = false #+END_SRC * Transparency and opacity @@ -202,7 +202,7 @@ describes the opacity of inactive windows. | Min value | ~0.1~ | | Max value | ~1.0~ | #+BEGIN_SRC conf - inactive-opacity = 0.6; +inactive-opacity = 0.6; #+END_SRC On the other hand, it is possible to declare a default opacity for active @@ -211,7 +211,7 @@ windows. | Min value | ~0.1~ | | Max value | ~1.0~ | #+BEGIN_SRC conf - active-opacity = 1; +active-opacity = 1; #+END_SRC This however describes the opacity of window titlebars and borders. @@ -219,7 +219,7 @@ This however describes the opacity of window titlebars and borders. | Min value | ~0.1~ | | Max value | ~1.0~ | #+BEGIN_SRC conf - frame-opacity = 1.0; +frame-opacity = 1.0; #+END_SRC ~menu-opacity~ describes the opacity for dropdown menus and popup menus. @@ -227,14 +227,14 @@ This however describes the opacity of window titlebars and borders. | Min value | ~0.1~ | | Max value | ~1.0~ | #+BEGIN_SRC conf - # menu-opacity = 0.9; +# menu-opacity = 0.9; #+END_SRC ~inactive-opacity-override~ allows the user to let inactive opacity set by ~-i~ override the ~_NET_WM_OPACITY_ values of windows. | Default value | ~true~ | #+BEGIN_SRC conf - inactive-opacity-override = true; +inactive-opacity-override = true; #+END_SRC While it is possible to alter opacity on inactive windows, it is also possible @@ -243,7 +243,7 @@ to dim them. | Min value | ~0.1~ | | Max value | ~1.0~ | #+BEGIN_SRC conf - # inactive-dim = 1.0 +# inactive-dim = 1.0 #+END_SRC It is also possible to use a fixed inactive dim value, instead of adjusting @@ -252,18 +252,18 @@ according to window opacity. | Min value | ~0.1~ | | Max value | ~1.0~ | #+BEGIN_SRC conf - # inactive-dim-fixed = 1.0 +# inactive-dim-fixed = 1.0 #+END_SRC It is also possible to specify a list of conditions of windows that should always be considered focused. | Default value | ~[]~ | #+BEGIN_SRC conf - focus-exclude = [ - "class_g = 'mpv'", - "class_g = 'qemu'", - "class_g = 'Qemu-system-x86_64'" - ]; +focus-exclude = [ + "class_g = 'mpv'", + "class_g = 'qemu'", + "class_g = 'Qemu-system-x86_64'" +]; #+END_SRC The user can also specify a list of opacity rules, in the format @@ -272,7 +272,7 @@ over this. Note we don't make any guarantee about possible conflicts with other programs that set ~_NET_WM_WINDOW_OPACITY~ on frame or client windows. | Default value | ~[]~ | #+BEGIN_SRC conf - opacity-rule = []; +opacity-rule = []; #+END_SRC * Background blurring @@ -282,13 +282,13 @@ programs that set ~_NET_WM_WINDOW_OPACITY~ on frame or client windows. The following are the parameters for background blurring, see the \*BLUR\* section for more information. #+BEGIN_SRC conf - blur: { - method = "dual_kawase"; - strength = 7; - background = false; - background-frame = false; - background-fixed = true; - } +blur: { + method = "dual_kawase"; + strength = 7; + background = false; + background-frame = false; + background-fixed = true; +} #+END_SRC This value enables or disables the blur for the background of semi-transparent @@ -296,39 +296,39 @@ or ARGB windows. It has bad performances though, with driver-dependent behavior. The name of the switch may change without prior notifications. | Default value | ~false~ | #+BEGIN_SRC conf - blur-background = true; +blur-background = true; #+END_SRC Blur background of windows when the window frame is not opaque. If true, this implies the value ~true~ for ~blur-background~. | Default value | ~false~ | #+BEGIN_SRC conf - blur-background-frame = true; +blur-background-frame = true; #+END_SRC The following determines whether to use fixed blur strength rather than adjusting according to window opacity. | Default value | ~false~ | #+BEGIN_SRC conf - blur-background-fixed = false; +blur-background-fixed = false; #+END_SRC Specify the blur convolution kernel, with the format ~"5,5,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1"~. | Default value | ~""~ | #+BEGIN_SRC conf - # blur-kern = "3x3box"; +# blur-kern = "3x3box"; #+END_SRC It is possible to write exclude conditions for background blur. | Default value | ~[]~ | #+BEGIN_SRC conf - blur-background-exclude = [ - "window_type = 'desktop'", - "class_g = 'Polybar'", - "class_g = 'discord-overlay'", - "_GTK_FRAME_EXTENTS@:c" - ]; +blur-background-exclude = [ + "window_type = 'desktop'", + "class_g = 'Polybar'", + "class_g = 'discord-overlay'", + "_GTK_FRAME_EXTENTS@:c" +]; #+END_SRC * General settings @@ -339,74 +339,74 @@ Daemonize process. Fork to background after initialization. Causes issues with certain (badly-written) drivers. | Default value | ~false~ | #+BEGIN_SRC conf - daemon = true; +daemon = true; #+END_SRC Picom has three backends it can use: ~xrender~, ~glx~, and ~xr_glx_hybrid~. GLX backend is typically much faster but depends on a sane driver. | Default value | ~xrender~ | #+BEGIN_SRC conf - backend = "glx"; +backend = "glx"; #+END_SRC This enables or disables VSync. | Default value | ~false~ | #+BEGIN_SRC conf - vsync = true; +vsync = true; #+END_SRC Enable remote control via D-Bus. See the *D-BUS API* section below for more details. | Default value | ~false~ | #+BEGIN_SRC conf - dbus = false; +dbus = false; #+END_SRC Try to detect WM windows (a non-override-redirect window with no child that has ~WM_STATE~) and markz them as active. | Default value | ~false~ | #+BEGIN_SRC conf - mark-wmwin-focused = true; +mark-wmwin-focused = true; #+END_SRC Mark override-redirect windows that doesn't have a child window with ~WM_STATE~ focused. | Default value | ~false~ | #+BEGIN_SRC conf - mark-ovredir-focused = true; +mark-ovredir-focused = true; #+END_SRC Try to detect windows with rounded corners and don't consider them shaped windows. The accuracy is not very high, unfortunately. | Default value | ~false~ | #+BEGIN_SRC conf - detect-rounded-corners = true; +detect-rounded-corners = true; #+END_SRC Detect ~_NET_WM_OPACITY~ on client windows, useful for window managers not passing ~_NET_WM_OPACITY~ of client windows to frame windows. | Default value | ~false~ | #+BEGIN_SRC conf - detect-client-opacity = true; +detect-client-opacity = true; #+END_SRC Specify refresh rate of the screen. If not specified or 0, picom will try detecting this with X RandR extension. | Default value | ~60~ | #+BEGIN_SRC conf - refresh-rate = 120; +refresh-rate = 120; #+END_SRC Limit picom to repaint at most once every 1 / ~refresh_rate~ second to boost performance. This should not be used with #+BEGIN_SRC text :tangle no - vsync drm/opengl/opengl-oml +vsync drm/opengl/opengl-oml #+END_SRC as they essentially does sw-opti's job already, unless you wish to specify a lower refresh rate than the actual value. | Default value | ~""~ | #+BEGIN_SRC conf - # sw-opti =; +# sw-opti =; #+END_SRC Use EWMH ~_NET_ACTIVE_WINDOW~ to determine currently focused window, rather than @@ -414,7 +414,7 @@ listening to ~FocusIn~/~FocusOut~ event. Might have more accuracy, provided that the WM supports it. | Default value | ~false~ | #+BEGIN_SRC conf - # use-ewmh-active-win = false; +# use-ewmh-active-win = false; #+END_SRC Unredirect all windows if a full-screen opaque window is detected, to maximize @@ -423,27 +423,27 @@ redirecting/unredirecting windows. paint-on-overlay may make the flickering less obvious. | Default value | ~false~ | #+BEGIN_SRC conf - unredir-if-possible = false; +unredir-if-possible = false; #+END_SRC Delay before unredirecting the window, in milliseconds. | Default value | ~0~ | #+BEGIN_SRC conf - unredir-if-possible-delay = 0; +unredir-if-possible-delay = 0; #+END_SRC Conditions of windows that shouldn't be considered full-screen for unredirecting screen. | Default value | ~[]~ | #+BEGIN_SRC conf - unredir-if-possible-exclude = []; +unredir-if-possible-exclude = []; #+END_SRC Use ~WM_TRANSIENT_FOR~ to group windows, and consider windows in the same group focused at the same time. | Default value | ~false~ | #+BEGIN_SRC conf - detect-transient = true; +detect-transient = true; #+END_SRC Use ~WM_CLIENT_LEADER~ to group windows, and consider windows in the same group @@ -451,7 +451,7 @@ focused at the same time. ~WM_TRANSIENT_FOR~ has higher priority if detect-transient is enabled, too. | Default value | ~false~ | #+BEGIN_SRC conf - detect-client-leader = true; +detect-client-leader = true; #+END_SRC Resize damaged region by a specific number of pixels. A positive value enlarges @@ -465,14 +465,14 @@ you use ~--resize-damage 2~, and so on). May or may not work with ~--glx-no-stencil~. Shrinking doesn't function correctly. | Default value | ~1~ | #+BEGIN_SRC conf - resize-damage = 1; +resize-damage = 1; #+END_SRC Specify a list of conditions of windows that should be painted with inverted color. Resource-hogging, and is not well tested. | Default value | ~[]~ | #+BEGIN_SRC conf - invert-color-include = []; +invert-color-include = []; #+END_SRC Disable the use of damage information. This cause the whole screen to be redrawn @@ -481,7 +481,7 @@ degrades the performance, but might fix some artifacts. The opposing option is use-damage | Default value | ~false~ | #+BEGIN_SRC conf - use-damage = false; +use-damage = false; #+END_SRC Use X Sync fence to sync clients' draw calls, to make sure all draw calls are @@ -489,21 +489,21 @@ finished before picom starts drawing. Needed on nvidia-drivers with GLX backend for some users. | Default value | ~false~ | #+BEGIN_SRC conf - xrender-sync-fence = false; +xrender-sync-fence = false; #+END_SRC Force all windows to be painted with blending. Useful if you have a glx-fshader-win that could turn opaque pixels transparent. | Default value | ~false~ | #+BEGIN_SRC conf - force-win-blend = false; +force-win-blend = false; #+END_SRC Do not use EWMH to detect fullscreen windows. Reverts to checking if a window is fullscreen based only on its size and coordinates. | Default value | ~false~ | #+BEGIN_SRC conf - no-ewmh-fullscreen = false; +no-ewmh-fullscreen = false; #+END_SRC Dimming bright windows so their brightness doesn't exceed this set value. @@ -512,14 +512,14 @@ this could comes with a performance hit. Setting this to 1.0 disables this behaviour. Requires ~--use-damage~ to be disabled. | Default value | ~1.0~ | #+BEGIN_SRC conf - max-brightness = 1.0; +max-brightness = 1.0; #+END_SRC Make transparent windows clip other windows like non-transparent windows do, instead of blending on top of them. | Default value | ~false~ | #+BEGIN_SRC conf - transparent-clipping = false; +transparent-clipping = false; #+END_SRC Set the log level. Possible values are: @@ -533,7 +533,7 @@ level, it's better to log into a file using ~--log-file~, since it can generate a huge stream of logs. | Default value | ~"debug"~ | #+BEGIN_SRC conf - log-level = "warn"; +log-level = "warn"; #+END_SRC Set the log file. If ~--log-file~ is never specified, logs will be written to @@ -542,19 +542,19 @@ early logs might still be written to the stderr. When setting this option from the config file, it is recommended to use an absolute path. | Default value | ~''~ | #+BEGIN_SRC conf - # log-file = '/path/to/your/log/file'; +# log-file = '/path/to/your/log/file'; #+END_SRC Show all X errors (for debugging) | Default value | ~false~ | #+BEGIN_SRC conf - # show-all-xerrors = false; +# show-all-xerrors = false; #+END_SRC Write process ID to a file. | Default value | ~''~ | #+BEGIN_SRC conf - # write-pid-path = '/path/to/your/log/file'; +# write-pid-path = '/path/to/your/log/file'; #+END_SRC Window type settings. ~WINDOW_TYPE~ is one of the 15 window types defined in @@ -588,14 +588,14 @@ Following per window-type options are available: unredir-if-possible set, and doesn't want certain window to cause unnecessary screen redirection, you can set this to `true`. #+BEGIN_SRC conf - wintypes: - { - tooltip = { fade = true; shadow = true; opacity = 0.75; focus = true; full-shadow = false; }; - dock = { shadow = false; } - dnd = { shadow = false; } - popup_menu = { opacity = 0.8; } - dropdown_menu = { opacity = 0.8; } - }; +wintypes: +{ + tooltip = { fade = true; shadow = true; opacity = 0.75; focus = true; full-shadow = false; }; + dock = { shadow = false; } + dnd = { shadow = false; } + popup_menu = { opacity = 0.8; } + dropdown_menu = { opacity = 0.8; } +}; #+END_SRC ** GLX backend-specific options @@ -608,7 +608,7 @@ practically happened) and may not work with blur-background. Tests show a 15% performance boost. Recommended. | Default value | ~false~ | #+BEGIN_SRC conf - glx-no-stencil = true; +glx-no-stencil = true; #+END_SRC Avoid rebinding pixmap on window damage. Probably could improve performance on @@ -616,7 +616,7 @@ rapid window content changes, but is known to break things on some drivers (LLVMpipe, xf86-video-intel, etc.). Recommended if it works. | Default value | ~false~ | #+BEGIN_SRC conf - glx-no-rebind-pixmap = false; +glx-no-rebind-pixmap = false; #+END_SRC Use specified GLSL fragment shader for rendering window contents. See @@ -624,5 +624,5 @@ Use specified GLSL fragment shader for rendering window contents. See ~compton-fake-transparency-fshader-win.glsl~ in the source tree for examples. | Default value | ~''~ | #+BEGIN_SRC conf :tangle no - glx-fshader-win = ''; +glx-fshader-win = ''; #+END_SRC diff --git a/org/config/rustfmt.org b/org/config/rustfmt.org index a057cdf..9600009 100644 --- a/org/config/rustfmt.org +++ b/org/config/rustfmt.org @@ -20,23 +20,23 @@ you can find how my Rust code is always formatted. :END: First, we are using the 2018 edition of Rust. #+BEGIN_SRC toml - edition = "2018" +edition = "2018" #+END_SRC Put single-expression functions on a single line. #+BEGIN_SRC toml - fn_single_line = true +fn_single_line = true #+END_SRC Format string literals where necessary. #+BEGIN_SRC toml - format_strings = true +format_strings = true #+END_SRC Maximum width of each line #+BEGIN_SRC toml - max_width = 80 +max_width = 80 #+END_SRC Merge multiple imports into a single nested import. #+BEGIN_SRC toml - merge_imports = true +merge_imports = true #+END_SRC * Structs and Enums @@ -50,15 +50,15 @@ purpose of alignment. Note that this is not how much whitespace is inserted, but instead the longest variant name that doesn't get ignored when aligning. #+BEGIN_SRC toml - enum_discrim_align_threshold = 20 +enum_discrim_align_threshold = 20 #+END_SRC The maximum diff of width between struct fields to be aligned with each other. #+BEGIN_SRC toml - struct_field_align_threshold = 20 +struct_field_align_threshold = 20 #+END_SRC Reorder impl items. ~type~ and ~const~ are put first, then macros and methods. #+BEGIN_SRC toml - reorder_impl_items = true +reorder_impl_items = true #+END_SRC * Comments @@ -67,19 +67,19 @@ Reorder impl items. ~type~ and ~const~ are put first, then macros and methods. :END: Convert ~/* */~ comments to ~//~ comments where possible. #+BEGIN_SRC toml - normalize_comments = true +normalize_comments = true #+END_SRC Break comments to fit on the line. #+BEGIN_SRC toml - wrap_comments = true +wrap_comments = true #+END_SRC Report ~FIXME~ items in comments. #+BEGIN_SRC toml - report_fixme = "Always" +report_fixme = "Always" #+END_SRC Report ~TODO~ items in comments. #+BEGIN_SRC toml - todo = "Always" +todo = "Always" #+END_SRC * Documentation @@ -88,11 +88,11 @@ Report ~TODO~ items in comments. :END: Format code snippet included in doc comments. #+BEGIN_SRC toml - format_code_in_doc_comments = true +format_code_in_doc_comments = true #+END_SRC Convert ~#![doc]~ and ~#[doc]~ attributes to ~//!~ and ~///~ doc comments. #+BEGIN_SRC toml - normalize_doc_attributes = true +normalize_doc_attributes = true #+END_SRC * Whitespace @@ -101,13 +101,13 @@ Convert ~#![doc]~ and ~#[doc]~ attributes to ~//!~ and ~///~ doc comments. :END: Use tab characters for indentation, spaces for alignment. #+BEGIN_SRC toml - hard_tabs = false +hard_tabs = false #+END_SRC Number of spaces per tab. #+BEGIN_SRC toml - tab_spaces = 4 +tab_spaces = 4 #+END_SRC I want newlines to always be Unix style. #+BEGIN_SRC toml - newline_style = "Unix" +newline_style = "Unix" #+END_SRC diff --git a/org/config/spacemacs.org b/org/config/spacemacs.org index 12d6047..c592ab1 100644 --- a/org/config/spacemacs.org +++ b/org/config/spacemacs.org @@ -25,16 +25,16 @@ file, then Emacs tangles them again, and then loads them. :header-args:emacs-lisp: :mkdirp yes :tangle ~/.emacs.spacemacs/private/spacemacs-layers.el :exports code :results silent :lexical t :END: #+BEGIN_SRC emacs-lisp :exports none - ;; -*- lexical-binding: t -*- +;; -*- lexical-binding: t -*- #+END_SRC Here will be our layer configuration set. Everything here is set with a ~setq-default~ in the ~dotspacemacs/layers~ function like so: #+BEGIN_SRC emacs-lisp :tangle no - (defun dotspacemacs/layers () - (setq-default - ;; configuration goes here - )) +(defun dotspacemacs/layers () + (setq-default + ;; configuration goes here + )) #+END_SRC ** General configuration @@ -45,7 +45,7 @@ First, we need to tell Spacemacs which base distribution we are using. This is a layer contained in the directory ~+distribution~. For now, available distributions are ~spacemacs-base~ and ~spacemacs~ (the default one). #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-distribution 'spacemacs) +(setq-default dotspacemacs-distribution 'spacemacs) #+END_SRC We can seet a lazy installation of layers —i.e. layers are installed only when a @@ -59,13 +59,13 @@ file with a supported type is opened. Possible values are: it. The default value is ~unused~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-enable-lazy-installation nil) +(setq-default dotspacemacs-enable-lazy-installation nil) #+END_SRC If the following variable is non-nil, Spacemacs will ask for confirmation before installing a layer lazily. The default value is ~t~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-ask-for-lazy-installation t) +(setq-default dotspacemacs-ask-for-lazy-installation t) #+END_SRC ** Package management @@ -76,8 +76,8 @@ It is possible to indicate to Spacemacs a list of additional paths where to look for configuration layers. Paths must have a trailing slash, i.e. =~/.mycontribs/=. As you can see, I added only one: #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-configuration-layer-path - '("~/fromGIT/emacs-packages")) +(setq-default dotspacemacs-configuration-layer-path + '("~/fromGIT/emacs-packages")) #+END_SRC However, I do have additional packages I installed either from the Elpa or the @@ -87,7 +87,7 @@ configuration for these packages, then I should consider creating a layer. I can also puth the configuration in ~dotspacemacs/user-config~. To use a local version of a package, use the ~:location~ property, for instance: #+BEGIN_SRC emacs-lisp :tangle no - '(your-package :location "~/path/to/your-package/") +'(your-package :location "~/path/to/your-package/") #+END_SRC With the variable ~dotspacemacs-additional-packages~, it is possible to install @@ -121,16 +121,16 @@ of all the extra packages I use: #+name: make-extra-pkg #+begin_src emacs-lisp :var packages=extra-packages[,0] :tangle no :exports none - (mapcar 'make-symbol packages) +(mapcar 'make-symbol packages) #+end_src #+begin_src emacs-lisp :noweb yes :exports none - (setq-default dotspacemacs-additional-packages '<>) +(setq-default dotspacemacs-additional-packages '<>) #+end_src It is possible to also list packages that cannot be updated: #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-frozen-packages '(helm-icons)) +(setq-default dotspacemacs-frozen-packages '(helm-icons)) #+END_SRC And to list packages which won’t be installed nor loaded: @@ -159,14 +159,14 @@ All layers are set one variable: ~dotspacemacs-configuration-layers~. This variable is a list of layers, some of them will have some custom variables. Typically, the variable will be set like so: #+BEGIN_SRC emacs-lisp :tangle no - (setq-default dotspacemacs-configuration-layers - '(emacs-lisp - helm - multiple-cursors - org - (shell :variables shell-default-height 30 - shell-default-position 'bottom) - treemacs)) +(setq-default dotspacemacs-configuration-layers + '(emacs-lisp + helm + multiple-cursors + org + (shell :variables shell-default-height 30 + shell-default-position 'bottom) + treemacs)) #+END_SRC # Don’t delete this code block, it wraps the layers @@ -181,10 +181,10 @@ Typically, the variable will be set like so: The two first checkers I use are for spell and syntax checking. ~spell-checking~ is disabled by default, however it should auto-detect the dictionary to use. #+BEGIN_SRC emacs-lisp - (spell-checking :variables - spell-checking-enable-by-default nil - spell-checking-enable-auto-dictionary t) - syntax-checking +(spell-checking :variables + spell-checking-enable-by-default nil + spell-checking-enable-auto-dictionary t) +syntax-checking #+END_SRC *** Completion @@ -198,18 +198,18 @@ auto-completion toolbox. I also want the autocompletion to include snippets in the popup, and the content of the popup is sorted by usage. It is also disabled for two modes: magit and Org. #+BEGIN_SRC emacs-lisp - (auto-completion :variables - auto-completion-complete-with-key-sequence-delay 0.2 - auto-completion-enable-help-tooltip 'manual - auto-completion-enable-sort-by-usage t - :disabled-for - org - git) +(auto-completion :variables + auto-completion-complete-with-key-sequence-delay 0.2 + auto-completion-enable-help-tooltip 'manual + auto-completion-enable-sort-by-usage t + :disabled-for + org + git) #+END_SRC ~helm~ is also enabled, with its header disabled. #+BEGIN_SRC emacs-lisp - (helm :variables helm-no-header t) +(helm :variables helm-no-header t) #+END_SRC *** Email @@ -220,11 +220,11 @@ I use as my daily Email client ~mu4e~, so let’s enable it and tell Emacs where mu4e is installed. I also tell mu4e to use maildirs extensions, use async operations, where to keep attachments, and enable the mu4e modeline. #+BEGIN_SRC emacs-lisp - (mu4e :variables - mu4e-installation-path "/usr/share/emacs/site-lisp" - mu4e-use-maildirs-extension t - mu4e-enable-mode-line t - mu4e-attachment-dir "~/Documents/mu4e") +(mu4e :variables + mu4e-installation-path "/usr/share/emacs/site-lisp" + mu4e-use-maildirs-extension t + mu4e-enable-mode-line t + mu4e-attachment-dir "~/Documents/mu4e") #+END_SRC *** Emacs @@ -237,15 +237,15 @@ respectively first move to the beginning of code first before going past the indentation and to the end of the code before going to the end of the line before going over the end of the comments on the same line. #+BEGIN_SRC emacs-lisp - (better-defaults :variables - better-defaults-move-to-beginning-of-code-first t - better-defaults-move-to-end-of-code-first t) +(better-defaults :variables + better-defaults-move-to-beginning-of-code-first t + better-defaults-move-to-end-of-code-first t) #+END_SRC I also enabled ~ibuffer~ and made it so that buffers are sorted by projects. #+BEGIN_SRC emacs-lisp - (ibuffer :variables - ibuffer-group-buffers-by 'projects) +(ibuffer :variables + ibuffer-group-buffers-by 'projects) #+END_SRC Most important of all, the ~org~ layer is also enabled. I enabled support for @@ -254,22 +254,22 @@ also enabled through files named ~TODOs.org~. I also set the org-download folder for images in =~/Pictures/org/=, and I set the =RET= key to follow org links if the cursor is on one. #+BEGIN_SRC emacs-lisp - (org :variables - org-enable-epub-support t - org-enable-github-support t - org-enable-hugo-support t - org-enable-reveal-js-support t - org-enable-sticky-header t - org-enable-appear-support t - spaceline-org-clock-p t - org-projectile-file "TODOs.org" - org-download-image-dir "~/Pictures/org/" - org-return-follows-link t) +(org :variables + org-enable-epub-support t + org-enable-github-support t + org-enable-hugo-support t + org-enable-reveal-js-support t + org-enable-sticky-header t + org-enable-appear-support t + spaceline-org-clock-p t + org-projectile-file "TODOs.org" + org-download-image-dir "~/Pictures/org/" + org-return-follows-link t) #+END_SRC The ~semantic~ layer is also enabled. #+BEGIN_SRC emacs-lisp - semantic +semantic #+END_SRC *** File trees @@ -281,9 +281,9 @@ so that treemacs syncs with my current buffer, and it automatically refreshes its buffer when there is a change in the part of the file system shown by treemacs. #+BEGIN_SRC emacs-lisp - (treemacs :variables - treemacs-use-follow-mode t - treemacs-use-filewatch-mode t) +(treemacs :variables + treemacs-use-follow-mode t + treemacs-use-filewatch-mode t) #+END_SRC *** Fonts @@ -293,22 +293,22 @@ treemacs. In this category, again, one layer is enabled: ~unicode-fonts~. This layer addssupport for the ~unicode-fonts~ package. #+BEGIN_SRC emacs-lisp - (unicode-fonts :variables - unicode-fonts-enable-ligatures t - unicode-fonts-ligature-modes '(prog-mode) - unicode-fonts-ligature-set '("|||>" "<|||" "<==>" "" "---" "-<<" - "<~~" "<~>" "<*>" "<||" "<|>" "<$>" "<==" "<=>" "<=<" "<->" - "<--" "<-<" "<<=" "<<-" "<<<" "<+>" "" "###" "#_(" "..<" - "..." "+++" "/==" "///" "_|_" "www" "&&" "^=" "~~" "~@" "~=" - "~>" "~-" "**" "*>" "*/" "||" "|}" "|]" "|=" "|>" "|-" "{|" - "[|" "]#" "::" ":=" ":>" ":<" "$>" "==" "=>" "!=" "!!" ">:" - ">=" ">>" ">-" "-~" "-|" "->" "--" "-<" "<~" "<*" "<|" "<:" - "<$" "<=" "<>" "<-" "<<" "<+" "" "++" "?:" - "?=" "?." "??" ";;" "/*" "/=" "/>" "//" "__" "~~" "(*" "*)" - "\\\\" "://")) +(unicode-fonts :variables + unicode-fonts-enable-ligatures t + unicode-fonts-ligature-modes '(prog-mode) + unicode-fonts-ligature-set '("|||>" "<|||" "<==>" "" "---" "-<<" + "<~~" "<~>" "<*>" "<||" "<|>" "<$>" "<==" "<=>" "<=<" "<->" + "<--" "<-<" "<<=" "<<-" "<<<" "<+>" "" "###" "#_(" "..<" + "..." "+++" "/==" "///" "_|_" "www" "&&" "^=" "~~" "~@" "~=" + "~>" "~-" "**" "*>" "*/" "||" "|}" "|]" "|=" "|>" "|-" "{|" + "[|" "]#" "::" ":=" ":>" ":<" "$>" "==" "=>" "!=" "!!" ">:" + ">=" ">>" ">-" "-~" "-|" "->" "--" "-<" "<~" "<*" "<|" "<:" + "<$" "<=" "<>" "<-" "<<" "<+" "" "++" "?:" + "?=" "?." "??" ";;" "/*" "/=" "/>" "//" "__" "~~" "(*" "*)" + "\\\\" "://")) #+END_SRC *** Fun @@ -317,7 +317,7 @@ addssupport for the ~unicode-fonts~ package. :END: In this category, I only enabled two layers: ~selectric~ and ~xkcd~. #+BEGIN_SRC emacs-lisp - selectric xkcd +selectric xkcd #+END_SRC *** Internationalization @@ -327,9 +327,9 @@ In this category, I only enabled two layers: ~selectric~ and ~xkcd~. In this category, I enabled the ~keyboard-layout~ layer to enable compatibility with the bépo layout. This layer, however, is disabled for magit, Dired and eww. #+BEGIN_SRC emacs-lisp - (keyboard-layout :variables - kl-layout 'bepo - kl-disabled-configurations '(magit dired eww)) +(keyboard-layout :variables + kl-layout 'bepo + kl-disabled-configurations '(magit dired eww)) #+END_SRC *** Programming languages @@ -345,68 +345,68 @@ Linux PKGBUILDs support, ~emacs-lisp~ and ~scheme~ layers, support for the CSV format with the ~csv~ layer, the ~yaml~ language, shell scripting languages and support for the ~dot~ tool with the ~graphviz~ layer. #+BEGIN_SRC emacs-lisp - major-modes emacs-lisp scheme graphviz yaml shell-scripts +major-modes emacs-lisp scheme graphviz yaml shell-scripts #+END_SRC I also added support for HTML and CSS with the ~html~ layer, with the web formatting tool set to ~web-beautify~, and the LSP layer compatibility enabled for CSS, less, SCSS and HTML. #+BEGIN_SRC emacs-lisp - (html :variables - web-fmt-tool 'web-beautify - css-enable-lsp t - less-enable-lsp t - scss-enable-lsp t - html-enable-lsp t) +(html :variables + web-fmt-tool 'web-beautify + css-enable-lsp t + less-enable-lsp t + scss-enable-lsp t + html-enable-lsp t) #+END_SRC The ~json~ layer is also enabled, with the format tool set to ~web-beautify~. #+BEGIN_SRC emacs-lisp - (json :variables - json-fmt-tool 'web-beautify) +(json :variables + json-fmt-tool 'web-beautify) #+END_SRC The LaTeX layer has also been enabled, with its default compiler set to XeLaTeX. I also enabled the auto-fill feature, the folding capacity and the “magic” symbols. #+BEGIN_SRC emacs-lisp - (latex :variables - latex-build-command "xelatex" - latex-enable-auto-fill t - latex-enable-folding t - latex-enable-magic t) +(latex :variables + latex-build-command "xelatex" + latex-enable-auto-fill t + latex-enable-folding t + latex-enable-magic t) #+END_SRC The Markdown layer has been enabled, with support for live preview with ~vmd~, and and automatic MMM-mode generation for C, C++, Python, Rust and Emacs Lisp. #+BEGIN_SRC emacs-lisp - (markdown :variables - markdown-live-preview-engine 'vmd - markdown-mmm-auto-modes '("c" - "c++" - "python" - "rust" - ("elisp" "emacs-lisp"))) +(markdown :variables + markdown-live-preview-engine 'vmd + markdown-mmm-auto-modes '("c" + "c++" + "python" + "rust" + ("elisp" "emacs-lisp"))) #+END_SRC PlantUML is a very useful DSL for creating UML diagrams from some text description. As you can see below, this layer will be enabled, both as a standalone mode for opening ~.pum~ files, but also for org-mode code blocks. #+BEGIN_SRC emacs-lisp - (plantuml :variables - plantuml-jar-path "~/.local/bin/plantuml.jar" - org-plantuml-jar-path "~/.local/bin/plantuml.jar") +(plantuml :variables + plantuml-jar-path "~/.local/bin/plantuml.jar" + org-plantuml-jar-path "~/.local/bin/plantuml.jar") #+END_SRC #+BEGIN_SRC emacs-lisp - (bibtex :variables - org-ref-default-bibliography '("~/Documents/Papers/references.bib") - org-ref-pdf-directory "~/Documents/Papers" - org-ref-bibliography-notes "~/Documents/Papers/notes.org") +(bibtex :variables + org-ref-default-bibliography '("~/Documents/Papers/references.bib") + org-ref-pdf-directory "~/Documents/Papers" + org-ref-bibliography-notes "~/Documents/Papers/notes.org") #+END_SRC #+BEGIN_SRC emacs-lisp - csv +csv #+END_SRC **** Frameworks @@ -416,7 +416,7 @@ standalone mode for opening ~.pum~ files, but also for org-mode code blocks. Only one framework support has been enabled so far, and is is for the Django framework. #+BEGIN_SRC emacs-lisp - django +django #+END_SRC **** General-purpose @@ -426,7 +426,7 @@ framework. Among the layers I activated, the only one without any specific configuration is the ~asm~ layer for the Assembly language. #+BEGIN_SRC emacs-lisp - asm +asm #+END_SRC Next, you can find the C/C++ layer for which I set the default language for ~.h~ @@ -435,38 +435,38 @@ include directives on a file save. I also set a couple of LSP-related variables, such as the LSP executable for C/C++ for its CCLS backend and some highlight variables. #+BEGIN_SRC emacs-lisp - (c-c++ :variables - c-c++-default-mode-for-headers 'c-mode - c-c++-adopt-subprojects t - c-c++-enable-c++11 t - c-c++-backend 'lsp-clangd - c-c++-lsp-enable-semantic-highlight t - c-c++-lsp-semantic-highlight-method 'overlay - c-c++-lsp-semantic-highlight-rainbow t - c++-enable-organize-includes-on-save t) +(c-c++ :variables + c-c++-default-mode-for-headers 'c-mode + c-c++-adopt-subprojects t + c-c++-enable-c++11 t + c-c++-backend 'lsp-clangd + c-c++-lsp-enable-semantic-highlight t + c-c++-lsp-semantic-highlight-method 'overlay + c-c++-lsp-semantic-highlight-rainbow t + c++-enable-organize-includes-on-save t) #+END_SRC Dart has also been enabled, with a custom path to the SDK of the Dart server, and to the LSP server of Dart. #+BEGIN_SRC emacs-lisp - (dart :variables - lsp-dart-project-sdk-dir "/opt/dart-sdk/" - lsp-dart-sdk-dir "/opt/dart-sdk/") +(dart :variables + lsp-dart-project-sdk-dir "/opt/dart-sdk/" + lsp-dart-sdk-dir "/opt/dart-sdk/") #+END_SRC When it comes to the Python layer, I set its backend and formatter to be bound to the LSP layer. Its fill columnn was also set to 80 characters, imports are sorted on save, and the tests can be run using either nose.el or pytest. #+BEGIN_SRC emacs-lisp - (python :variables - python-fill-column 80 - python-test-runner '(pytest nose)) +(python :variables + python-fill-column 80 + python-test-runner '(pytest nose)) #+END_SRC With the Rust layer, the only custom configuration set is the backend being bound to the LSP layer. #+BEGIN_SRC emacs-lisp - (rust :variables rust-backend 'lsp) +(rust :variables rust-backend 'lsp) #+END_SRC As regards the JavaScript layer, I set its backend to the LSP layer, and bound @@ -474,32 +474,32 @@ its format tool to ~web-beautify~ and its REPL is browser-based. I also want to include ~node_modules/.bin~ to be automatically added to the buffer local ~exec_path~. #+BEGIN_SRC emacs-lisp - (javascript :variables - javascript-backend 'lsp - javascript-fmt-tool 'web-beautify - javascript-repl 'skewer - node-add-modules-path t) +(javascript :variables + javascript-backend 'lsp + javascript-fmt-tool 'web-beautify + javascript-repl 'skewer + node-add-modules-path t) #+END_SRC Alternatively, I also use Typescript which is a sort of better Javascript as it should have been, with the LSP backend. #+BEGIN_SRC emacs-lisp - (typescript :variables - typescript-backend 'lsp) +(typescript :variables + typescript-backend 'lsp) #+END_SRC I am also currently using the Awesome window manager which requires the Lua programming language, so here it is. #+BEGIN_SRC emacs-lisp - (lua :variables - lua-backend 'lsp-emmy - lua-lsp-emmy-jar-path "~/.config/awesome/EmmyLua-LS-all.jar" - lua-lsp-emmy-java-path "java" - lua-lsp-emmy-enable-file-watchers t) +(lua :variables + lua-backend 'lsp-emmy + lua-lsp-emmy-jar-path "~/.config/awesome/EmmyLua-LS-all.jar" + lua-lsp-emmy-java-path "java" + lua-lsp-emmy-enable-file-watchers t) #+END_SRC #+BEGIN_SRC emacs-lisp - (php :variables php-backend 'lsp) +(php :variables php-backend 'lsp) #+END_SRC *** Readers @@ -513,7 +513,7 @@ programming language, so here it is. In this category, only the ~epub~ and ~pdf~ layers are enabled without any special configuration, so I can read these files from Emacs directly. #+BEGIN_SRC emacs-lisp - epub pdf +epub pdf #+END_SRC **** Elfeed @@ -523,8 +523,8 @@ special configuration, so I can read these files from Emacs directly. Elfeed is an Emacs feeed and RSS reader which can be managed through org files. Actually, through only one file in my case, located in my =~/org= directory. #+BEGIN_SRC emacs-lisp - (elfeed :variables - rmh-elfeed-org-files '("~/org/elfeed.org")) +(elfeed :variables + rmh-elfeed-org-files '("~/org/elfeed.org")) #+END_SRC *** Version control @@ -543,7 +543,7 @@ git Here, the ~colors~ layer is the only one enabled. It activates support for identifiers colorization, and strings representing colors. #+BEGIN_SRC emacs-lisp - colors +colors #+END_SRC *** Tools @@ -553,37 +553,37 @@ identifiers colorization, and strings representing colors. In this category, the first layer to be enabled is the CMake layer for which I enabled support for the ~cmake-ide~ package. #+BEGIN_SRC emacs-lisp - (cmake :variables - cmake-enable-cmake-ide-support t) +(cmake :variables + cmake-enable-cmake-ide-support t) #+END_SRC Next, we have the Docker, Nginx, Pass (the standard Unix password manager), Prettier, Systemd, Meson, Imenu-list, Web-beautify, Dap, and Helpful. #+BEGIN_SRC emacs-lisp - dap docker helpful imenu-list meson nginx pass prettier systemd web-beautify +dap docker helpful imenu-list meson nginx pass prettier systemd web-beautify #+END_SRC Of course, let’s not forget about the awesome LSP layer: #+BEGIN_SRC emacs-lisp - (lsp :variables lsp-lens-enable t - lsp-use-lsp-ui t - lsp-rust-server 'rust-analyzer) +(lsp :variables lsp-lens-enable t + lsp-use-lsp-ui t + lsp-rust-server 'rust-analyzer) #+END_SRC We also have the RestClient layer enabled for which I enabled the Org compatibility support. #+BEGIN_SRC emacs-lisp - (restclient :variables - restclient-use-org t) +(restclient :variables + restclient-use-org t) #+END_SRC LanguageTool works with Flyspell and will check for grammatical issues in my english texts. #+BEGIN_SRC emacs-lisp - (languagetool :variables - langtool-default-language "en-US" - languagetool-show-error-on-jump t - langtool-java-classpath "/usr/share/languagetool:/usr/share/java/languagetool/*") +(languagetool :variables + langtool-default-language "en-US" + languagetool-show-error-on-jump t + langtool-java-classpath "/usr/share/languagetool:/usr/share/java/languagetool/*") #+END_SRC @@ -591,10 +591,10 @@ And finally, we also have the Shell layer for which I specified its default height when spawning at the bottom of the screen should be 40 lines high, and the default shell to invoke is Eshell. #+BEGIN_SRC emacs-lisp - (shell :variables - shell-default-height 40 - shell-default-position 'bottom - shell-default-shell 'eshell) +(shell :variables + shell-default-height 40 + shell-default-position 'bottom + shell-default-shell 'eshell) #+END_SRC *** Web Services @@ -613,7 +613,7 @@ twitter Lastly, one custom layers have been enabled: my custom layer for conlanging tools. #+BEGIN_SRC emacs-lisp - conlanging +conlanging #+END_SRC # Don’t delete this code block, it wraps the layers @@ -627,7 +627,7 @@ tools. :CUSTOM_ID: Init-99a4b561 :END: #+BEGIN_SRC emacs-lisp :exports none - ;; -*- lexical-binding: t -*- +;; -*- lexical-binding: t -*- #+END_SRC The ~dotspacemacs/init~ function is the one called at the very begining of the @@ -637,10 +637,10 @@ here. By default, every values are set in a ~setq-default~ sexp, and they represent all the supported Spacemacs settings. Hence, the function looks like this: #+BEGIN_SRC emacs-lisp :tangle no - (defun dotspacemacs/init () - (setq-default - ;; default Spacemacs configuration here - )) +(defun dotspacemacs/init () + (setq-default + ;; default Spacemacs configuration here + )) #+END_SRC ** Handling my Spacemacs litterate config @@ -654,34 +654,34 @@ about how I manage writing a litterate config for Spacemacs and ensure Emacs starts with an up-to-date configuration from said litterate config. For that, I actually declared a couple of variables: #+BEGIN_SRC emacs-lisp - (defvar phundrak--dotspacemacs-src-dir "~/.emacs.spacemacs/private/" - "Directory for my exported Elisp configuration files") - (defvar phundrak--dotspacemacs-src "~/org/config/emacs.org" - "My litterate config file for Emacs") - (defvar phundrak--dotspacemacs-si (concat phundrak--dotspacemacs-src-dir "spacemacs-init")) - (defvar phundrak--dotspacemacs-sl (concat phundrak--dotspacemacs-src-dir "spacemacs-layers")) - (defvar phundrak--dotspacemacs-uc (concat phundrak--dotspacemacs-src-dir "user-config")) - (defvar phundrak--dotspacemacs-ui (concat phundrak--dotspacemacs-src-dir "user-init")) - (defvar phundrak--dotspacemacs-files (list phundrak--dotspacemacs-si phundrak--dotspacemacs-sl - phundrak--dotspacemacs-uc phundrak--dotspacemacs-ui)) +(defvar phundrak--dotspacemacs-src-dir "~/.emacs.spacemacs/private/" + "Directory for my exported Elisp configuration files") +(defvar phundrak--dotspacemacs-src "~/org/config/emacs.org" + "My litterate config file for Emacs") +(defvar phundrak--dotspacemacs-si (concat phundrak--dotspacemacs-src-dir "spacemacs-init")) +(defvar phundrak--dotspacemacs-sl (concat phundrak--dotspacemacs-src-dir "spacemacs-layers")) +(defvar phundrak--dotspacemacs-uc (concat phundrak--dotspacemacs-src-dir "user-config")) +(defvar phundrak--dotspacemacs-ui (concat phundrak--dotspacemacs-src-dir "user-init")) +(defvar phundrak--dotspacemacs-files (list phundrak--dotspacemacs-si phundrak--dotspacemacs-sl + phundrak--dotspacemacs-uc phundrak--dotspacemacs-ui)) #+END_SRC I also declared the following function that tells me if my Elisp files are more recent than my ~emacs.org~ file. The ~compiled?~ argument lets me compare either the ~.el~ files if it is ~nil~, or the ~.elc~ files if it is ~t~. #+BEGIN_SRC emacs-lisp - (defun phundrak-update-config-files-p (&optional compiled?) - "Verify if any of my exported Elisp configuration files are - newer than my litterate configuration. +(defun phundrak-update-config-files-p (&optional compiled?) + "Verify if any of my exported Elisp configuration files are +newer than my litterate configuration. - If `COMPILED?' is `t', check the `.elc' files instead of the - `.el' files." - (catch 'ret - (dolist (file phundrak--dotspacemacs-files) - (when (file-newer-than-file-p phundrak--dotspacemacs-src - (format "%s.%s" - file - (if compiled? "elc" "el"))) - (throw 'ret t))))) +If `COMPILED?' is `t', check the `.elc' files instead of the +`.el' files." + (catch 'ret + (dolist (file phundrak--dotspacemacs-files) + (when (file-newer-than-file-p phundrak--dotspacemacs-src + (format "%s.%s" + file + (if compiled? "elc" "el"))) + (throw 'ret t))))) #+END_SRC Now I know a couple of my files that get exported by this document. If I compare @@ -691,22 +691,22 @@ missed tangling its configuration before launching, so if any of my ~si~, ~sl~, and since my user config is growing longer and longer, I want Emacs to be able to parse it fast next time it boots, so let’s compile my exported ~.el~ files! #+BEGIN_SRC emacs-lisp - (when (or (file-newer-than-file-p phundrak--dotspacemacs-src (concat phundrak--dotspacemacs-si ".el")) - (file-newer-than-file-p phundrak--dotspacemacs-src (concat phundrak--dotspacemacs-sl ".el")) - (file-newer-than-file-p phundrak--dotspacemacs-src (concat phundrak--dotspacemacs-ui ".el")) - (file-newer-than-file-p phundrak--dotspacemacs-src (concat phundrak--dotspacemacs-uc ".el"))) - (message "Exporting new Emacs configuration from spacemacs.org through org-babel...") - (with-temp-buffer - (shell-command (format "emacs -Q --batch %s %s %s" - "--eval \"(require 'ob-tangle)\"" - "--eval \"(setq org-confirm-babel-evaluate nil)\"" - (format "--eval '(org-babel-tangle-file \"%s\")'" - phundrak--dotspacemacs-src)) - (current-buffer))) - (message "Exporting new Emacs configuration from spacemacs.org through org-babel...done") - (with-temp-buffer - (byte-recompile-directory phundrak--dotspacemacs-src-dir - 0 t))) +(when (or (file-newer-than-file-p phundrak--dotspacemacs-src (concat phundrak--dotspacemacs-si ".el")) + (file-newer-than-file-p phundrak--dotspacemacs-src (concat phundrak--dotspacemacs-sl ".el")) + (file-newer-than-file-p phundrak--dotspacemacs-src (concat phundrak--dotspacemacs-ui ".el")) + (file-newer-than-file-p phundrak--dotspacemacs-src (concat phundrak--dotspacemacs-uc ".el"))) + (message "Exporting new Emacs configuration from spacemacs.org through org-babel...") + (with-temp-buffer + (shell-command (format "emacs -Q --batch %s %s %s" + "--eval \"(require 'ob-tangle)\"" + "--eval \"(setq org-confirm-babel-evaluate nil)\"" + (format "--eval '(org-babel-tangle-file \"%s\")'" + phundrak--dotspacemacs-src)) + (current-buffer))) + (message "Exporting new Emacs configuration from spacemacs.org through org-babel...done") + (with-temp-buffer + (byte-recompile-directory phundrak--dotspacemacs-src-dir + 0 t))) #+END_SRC All that’s left to do in the Spacemacs functions is to call ~load~ on ~si~, ~sl~, ~uc~, and ~ui~. Be aware this sub-chapter won’t be tangled, so it might @@ -723,14 +723,14 @@ feature yet, as I am still on Emacs 26 provided from Arch Linux’s repositories so I’ll disable the Spacemacs support for this feature. The default value of this variable is ~nil~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-enable-emacs-pdumper t) +(setq-default dotspacemacs-enable-emacs-pdumper t) #+END_SRC In case the support for pdumper was enabled, Spacemacs needs to know the name of the Emacs executable which supports such a feature. The executable must be in the user’s ~PATH~. By default, the value of the variable is ~"emacs"~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-emacs-pdumper-executable-file "emacs") +(setq-default dotspacemacs-emacs-pdumper-executable-file "emacs") #+END_SRC And finally, we can name the Spacemacs dump file. This is the file that will be @@ -739,13 +739,13 @@ sub-directory. To load it when starting Emacs, the parameter ~--dump-file~ should be added when invoking Emacs 27.1 executable from the command line, for instance: #+BEGIN_SRC sh :tangle no :exports code - ./emacs --dump-file=~/.emacs.spacemacs/.cache/dumps/spacemacs.pdmp +./emacs --dump-file=~/.emacs.spacemacs/.cache/dumps/spacemacs.pdmp #+END_SRC The default value of this variable is ~"spacemacs.pdmp"~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-emacs-dumper-dump-file - (format "spacemacs-%s.pdmp" emacs-version)) +(setq-default dotspacemacs-emacs-dumper-dump-file + (format "spacemacs-%s.pdmp" emacs-version)) #+END_SRC ** Package managment and updates @@ -757,7 +757,7 @@ services. If Spacemacs is not set to the ~develop~ branch, it can check by itself if any update is available. However, I am using said branch, therefore I should set this variable to ~nil~. The default value is ~nil~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-check-for-update nil) +(setq-default dotspacemacs-check-for-update nil) #+END_SRC When it comes to package management, Spacemacs is able to store them in @@ -766,13 +766,13 @@ variables. I personally prefer to use the value ~emacs-version~ since it makes it easier to upgrade or downgrade Emacs without any conflict with the already installed packages. The default value is ~emacs-version~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-elpa-subdirectory 'emacs-version) +(setq-default dotspacemacs-elpa-subdirectory 'emacs-version) #+END_SRC Spacemacs has a capacity of performing rollbacks after updates. We can set the maximum number of rollback slots to keep in the cache. The default value is ~5~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-max-rollback-slots 5) +(setq-default dotspacemacs-max-rollback-slots 5) #+END_SRC *** Elpa repository @@ -792,7 +792,7 @@ default value is ~t~. We can set a maximum amount of seconds which will represent the maximum allowed time to contact the Elpa repository. By default, this setting is set on ~5~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-elpa-timeout 5) +(setq-default dotspacemacs-elpa-timeout 5) #+END_SRC *** Spacelpa repository @@ -811,7 +811,7 @@ set to ~nil~. The default value is ~nil~. If the below value is not ~nil~, then the signature for the downloaded Spacelpa packages must be verified. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-verify-spacelpa-archives t) +(setq-default dotspacemacs-verify-spacelpa-archives t) #+END_SRC ** Editing style @@ -832,17 +832,17 @@ The value can also be a list with the ~:variables~ keyword (similar to layers). Check the editing styles section of the documentation for details on available variables. The default value is ~vim~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-editing-style - '(hybrid :variables - hybrid-mode-enable-evilified-state t - hybrid-mode-default-state 'normal)) +(setq-default dotspacemacs-editing-style + '(hybrid :variables + hybrid-mode-enable-evilified-state t + hybrid-mode-default-state 'normal)) #+END_SRC If non-nil, the paste transient-state is enabled. While enabled, after you paste something, pressing ~C-j~ and ~C-k~ several times cycles through the elements in the ~kill-ring~. Default ~nil~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-enable-paste-transient-state t) +(setq-default dotspacemacs-enable-paste-transient-state t) #+END_SRC ** Spacemacs home configuration @@ -872,20 +872,20 @@ The order in which they are set in the below list affects their order on the Spacemacs startup page. List sikes may be ~nil~, in which case ~spacemacs-buffer-startup-lists-length~ takes effect. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-startup-lists '((recents . 15) - (projects . 15))) +(setq-default dotspacemacs-startup-lists '((recents . 15) + (projects . 15))) #+END_SRC The below variable allows the startup page to respond to resize events. Its default value is ~t~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-startup-buffer-responsive t) +(setq-default dotspacemacs-startup-buffer-responsive t) #+END_SRC If non-nil show the version string in the Spacemacs buffer. It will appear as ~(spacemacs version)@(emacs version)~. Default ~t~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-startup-buffer-show-version t) +(setq-default dotspacemacs-startup-buffer-show-version t) #+END_SRC ** Default major modes @@ -924,12 +924,12 @@ Spacemacs makes it quite easy to use themes and organize them. The below value is a list of themes, the first of the list is loaded when Spacemacs starts. The user can press ~SPC T n~ to cycle to the next theme in the list. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-themes '(nord doom-nord doom-vibrant spacemacs-dark - doom-one doom-opera doom-dracula doom-molokai - doom-peacock doom-sourcerer doom-spacegrey - kaolin-dark kaolin-aurora kaolin-bubblegum - kaolin-galaxy kaolin-mono-dark kaolin-temple - kaolin-valley-dark)) +(setq-default dotspacemacs-themes '(nord doom-nord doom-vibrant spacemacs-dark + doom-one doom-opera doom-dracula doom-molokai + doom-peacock doom-sourcerer doom-spacegrey + kaolin-dark kaolin-aurora kaolin-bubblegum + kaolin-galaxy kaolin-mono-dark kaolin-temple + kaolin-valley-dark)) #+END_SRC Emacs also makes use of themes for the Spaceline at the bottom of buffers. @@ -946,15 +946,15 @@ refer to Spacemacs’ ~DOCUMENTATION.org~ file for more info on how to create yo own Spaceline theme. Value can be a symbol or list with additional properties. The default value is ~'(spacemacs :separator wave :separator-scale 1.5))~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-mode-line-theme '(doom - :separator wave - :separator-scale 1.0)) +(setq-default dotspacemacs-mode-line-theme '(doom + :separator wave + :separator-scale 1.0)) #+END_SRC It is also possible to color the cursor depending on which mode Spacemacs is in, in order to mach the state color in GUI Emacs. The default value is ~t~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-colorize-cursor-according-to-state t) +(setq-default dotspacemacs-colorize-cursor-according-to-state t) #+END_SRC The below variable sets either the default font or a prioritized list of fonts @@ -963,14 +963,14 @@ to be used by Emacs. The ~:size~ can be specified as a non-negative integer because it’s device independent (add a ~.0~ to make an integer a floating point). The default size is ~10.0~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-default-font '("Cascadia Code" - :size 9.0)) +(setq-default dotspacemacs-default-font '("Cascadia Code" + :size 9.0)) #+END_SRC I also added the following code in order to define a fallback font for emojis, defined only on their unicode range: #+BEGIN_SRC emacs-lisp - (set-fontset-font "fontset-default" '(#x1f600 . #x1f64f) "NotoEmoji Nerd Font") +(set-fontset-font "fontset-default" '(#x1f600 . #x1f64f) "NotoEmoji Nerd Font") #+END_SRC *** Other on-screen elements @@ -981,7 +981,7 @@ defined only on their unicode range: variable sets in seconds the time Spacemacs should wait between a key press and the moment ~which-key~ should be shown. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-which-key-delay 1) +(setq-default dotspacemacs-which-key-delay 1) #+END_SRC This variable sets ~which-key~'s frame position. Possible values are: @@ -991,7 +991,7 @@ This variable sets ~which-key~'s frame position. Possible values are: ~right-then-bottom~ tries to display the frame to the right, but if there is insufficient space it displays it at the bottom. The default value is ~bottom~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-which-key-position 'right-then-bottom) +(setq-default dotspacemacs-which-key-position 'right-then-bottom) #+END_SRC This controls where ~switch-to-buffer~ displays the buffer. If the value is @@ -1000,40 +1000,40 @@ another same-purpose window is available. If non-nil, ~switch-to-buffer~ displays the buffer in a same-purpose window even if the buffer can be displayed in the current window. The default value is ~nil~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-switch-to-buffer-prefers-purpose nil) +(setq-default dotspacemacs-switch-to-buffer-prefers-purpose nil) #+END_SRC If this variable is non-nil, a progress bar is displayed when Spacemacs is loading. This may increase the boot time on some systems and emacs builds, set it to ~nil~ to boost the loading time. The default value is ~t~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-loading-progress-bar t) +(setq-default dotspacemacs-loading-progress-bar t) #+END_SRC If the value is non-nil, Emacs will show the title of the transient states. The default value is ~t~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-show-transient-state-title t) +(setq-default dotspacemacs-show-transient-state-title t) #+END_SRC If non-nil, this will show the color guide hint for transient state keys. The default value is ~t~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-show-transient-state-color-guide t) +(setq-default dotspacemacs-show-transient-state-color-guide t) #+END_SRC If non-nil, unicode symbols are displayed in the mode line. If you use Emacs as a daemon and want unicode characters only in GUI set the value to quoted ~display-graphic-p~. The default value is ~t~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-mode-line-unicode-symbols t) +(setq-default dotspacemacs-mode-line-unicode-symbols t) #+END_SRC If non-nil, smooth scrolling (native-scrolling) is enabled. Smooth scrolling overrides the default behavior of Emacs which recenters point when it reaches the top or bottom of the screen. The default value is ~t~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-smooth-scrolling t) +(setq-default dotspacemacs-smooth-scrolling t) #+END_SRC The following value controls the line number activation. If set to ~t~, @@ -1044,24 +1044,24 @@ For example, folded lines will not be counted and wrapped lines are counted as multiple lines. This variable can also be set to a property list for finer control: #+BEGIN_SRC emacs-lisp :tangle no - '(:relative nil - :visual nil - :disabled-for-modes dired-mode - doc-view-mode - markdown-mode - org-mode - pdf-view-mode - text-mode - :size-limit-kb 1000) +'(:relative nil + :visual nil + :disabled-for-modes dired-mode + doc-view-mode + markdown-mode + org-mode + pdf-view-mode + text-mode + :size-limit-kb 1000) #+END_SRC When used in a plist, ~visual~ takes precendence over ~relative~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-line-numbers '(:relative nil - :visual nil - :disabled-for-modes org-mode pdf-view-mode - dired-mode doc-view-mode - text-mode)) +(setq-default dotspacemacs-line-numbers '(:relative nil + :visual nil + :disabled-for-modes org-mode pdf-view-mode + dired-mode doc-view-mode + text-mode)) #+END_SRC Select a scope to highlight delimiter. Possible values are: @@ -1071,25 +1071,25 @@ Select a scope to highlight delimiter. Possible values are: - ~nil~ The default value is ~all~ (highlights any scope and emphasis the current one). #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-highlight-delimiters 'all) +(setq-default dotspacemacs-highlight-delimiters 'all) #+END_SRC After a certain amount of time in seconds, Spacemacs can zone-out. The default value is ~nil~. I set it so Spacemacs zones out after 15 minutes. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-zone-out-when-idle 900) +(setq-default dotspacemacs-zone-out-when-idle 900) #+END_SRC Run ~spacemacs/prettify-org-buffer~ when visiting the ~README.org~ files of Spacemacs. The default value is ~nil~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-pretty-docs nil) +(setq-default dotspacemacs-pretty-docs nil) #+END_SRC If ~nil~, the home buffer shows the full path of agenda items and todos. If non ~nil~, only the file name is shown. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-home-shorten-agenda-source t) +(setq-default dotspacemacs-home-shorten-agenda-source t) #+END_SRC *** Appearance of Emacs frames @@ -1100,14 +1100,14 @@ Starting from Emacs 24.4, it is possible to make the Emacs frame fullscreen when Emacs starts up if the variable is set to a non-nil value. The default value is ~nil~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-fullscreen-at-startup nil) +(setq-default dotspacemacs-fullscreen-at-startup nil) #+END_SRC This variable is to be used if the user does not want to use native fullscreen with ~spacemacs/toggle-fullscreen~. This disables for instance the fullscreen animation under OSX. The default value is ~nil~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-fullscreen-use-non-native nil) +(setq-default dotspacemacs-fullscreen-use-non-native nil) #+END_SRC If you do not start Emacs in fullscreen at startup, you might want it to be @@ -1123,7 +1123,7 @@ If non-nil, the frame is undecorated when Emacs starts up. Combine this with the variable ~dotspacemacs-maximized-at-startup~ in OSX to obtain borderless fullscreen. The default value is ~nil~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-undecorated-at-startup nil) +(setq-default dotspacemacs-undecorated-at-startup nil) #+END_SRC You can also set a transparency level for Emacs when you toggle the transparency @@ -1131,14 +1131,14 @@ of the frame with ~toggle-transparency~. The value of the transparency, going from 0 to 100 in increasing opacity, describes the transparency level of a frame when it’s active or selected. The default value is ~90~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-active-transparency 85) +(setq-default dotspacemacs-active-transparency 85) #+END_SRC Similarly, you can set a value from 0 to 100 in increasing opacity which describes the transparency level of a frame when it’s inactive or deselected. The default value is ~90~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-inactive-transparency 80) +(setq-default dotspacemacs-inactive-transparency 80) #+END_SRC The variable below sets the format of frame title. You can use: @@ -1160,13 +1160,13 @@ The variable below sets the format of frame title. You can use: - ~%Z~ :: like ~%z~, but including the end-of-line format The default value is ~"%I@%S"~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-frame-title-format "Emacs: %b (%t) %U@%S") +(setq-default dotspacemacs-frame-title-format "Emacs: %b (%t) %U@%S") #+END_SRC Format specification for setting the icon title format. The default value is ~nil~, same as ~frame-title-format~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-icon-title-format nil) +(setq-default dotspacemacs-icon-title-format nil) #+END_SRC ** Spacemacs leader keys and shortcuts @@ -1176,39 +1176,39 @@ Format specification for setting the icon title format. The default value is The below setting sets the Spacemacs leader key. By default, this is the ~SPC~ key. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-leader-key "SPC") +(setq-default dotspacemacs-leader-key "SPC") #+END_SRC Once the leader key has been pressed, it is possible to set another key in order to call Emacs’ command ~M-x~. By default, it is again the ~SPC~ key. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-emacs-command-key "SPC") +(setq-default dotspacemacs-emacs-command-key "SPC") #+END_SRC It is also possible to invoke Vim Ex commands with the press of a key, and by default it is the ~:~ key. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-ex-command-key ":") +(setq-default dotspacemacs-ex-command-key ":") #+END_SRC The below variable sets the leader key accessible in ~emacs-state~ and ~insert-state~: #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-emacs-leader-key "M-m") +(setq-default dotspacemacs-emacs-leader-key "M-m") #+END_SRC The major mode leader key is a shortcut key which is the equivalent of pressing ~ m~. Set it to ~nil~ to disable it. Its default value is ~,~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-major-mode-leader-key ",") +(setq-default dotspacemacs-major-mode-leader-key ",") #+END_SRC In ~emacs-state~ and ~insert-state~, the same major mode leader key can be accessible from another shortcut, which by default is ~C-M-m~ in terminal mode, or ~M-return~ in GUI mode. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-major-mode-emacs-leader-key - (if window-system "" "C-M-m")) +(setq-default dotspacemacs-major-mode-emacs-leader-key + (if window-system "" "C-M-m")) #+END_SRC These variables control whether separate commands are bound in the GUI to the @@ -1217,7 +1217,7 @@ allows for separate commands under ~C-i~ and ~TAB~, and ~C-m~ and ~RET~. In the terminal, these pairs are generally indistinguishable, so this only works in the GUI. The default value is ~nil~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-distinguish-gui-tab nil) +(setq-default dotspacemacs-distinguish-gui-tab nil) #+END_SRC ** Layouts @@ -1227,26 +1227,26 @@ GUI. The default value is ~nil~. The variable belows sets the name of the default layout. Its default value is ~"Default"~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-default-layout-name "Default") +(setq-default dotspacemacs-default-layout-name "Default") #+END_SRC If non-nil, the default layout name is displayed in the mode-line. The default value is ~nil~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-display-default-layout nil) +(setq-default dotspacemacs-display-default-layout nil) #+END_SRC If non-nil, then the last auto saved layouts are resumed automatically upon start. The default value is ~nil~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-auto-resume-layouts nil) +(setq-default dotspacemacs-auto-resume-layouts nil) #+END_SRC If non-nil, the layout name will be auto-generated when creating new layouts. It only has an effect when using the “jump to layout by number” command. The default value is ~nil~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-auto-generate-layout-names nil) +(setq-default dotspacemacs-auto-generate-layout-names nil) #+END_SRC ** Files-related settings @@ -1266,7 +1266,7 @@ This variable sets the location where to auto-save files. Possible values are: - ~nil~ :: disables auto-saving. The default value is ~cache~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-auto-save-file-location 'original) +(setq-default dotspacemacs-auto-save-file-location 'original) #+END_SRC ** Emacs server @@ -1276,7 +1276,7 @@ The default value is ~cache~. Emacs can be launched as a server if the following value is set to non-nil and if one isn’t already running. The default value is ~nil~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-enable-server nil) +(setq-default dotspacemacs-enable-server nil) #+END_SRC You can also set a custom emacs server socket location. If the value is ~nil~, @@ -1284,13 +1284,13 @@ Emacs will use whatever the Emacs default is, otherwise a directory path like ="$HOME/.config/emacs/server"=. It has no effect if ~dotspacemacs-enable-server~ is ~nil~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-server-socket-dir nil) +(setq-default dotspacemacs-server-socket-dir nil) #+END_SRC It is also possible to tell Emacs that the quit function should keep the server open when quitting. The default value is ~nil~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-persistent-server t) +(setq-default dotspacemacs-persistent-server t) #+END_SRC ** Miscellaneous @@ -1300,20 +1300,20 @@ open when quitting. The default value is ~nil~. This value changes the folding method of code blocks. The possible values are either ~evil~, the default value, or ~origami~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-folding-method 'evil) +(setq-default dotspacemacs-folding-method 'evil) #+END_SRC If non-nil, ~smartparens-strict-mode~ will be enabled in programming modes. The default value is ~nil~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-smartparens-strict-mode nil) +(setq-default dotspacemacs-smartparens-strict-mode nil) #+END_SRC If non-nil, pressing the closing parenthesis ~)~ key in insert mode passes over any automatically added closing parenthesis, bracket, quote, etc… This can temporarily disabled by pressing ~C-q~ before ~)~. The default value is ~nil~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-smart-closing-parenthesis nil) +(setq-default dotspacemacs-smart-closing-parenthesis nil) #+END_SRC List of search tool executable names. Spacemacs uses the first installed tool of @@ -1325,7 +1325,7 @@ the list. Supported tools are: - ~grep~ The default value is ~'("rg" "ag" "pt" "ack" "grep")~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-search-tools '("rg" "grep")) +(setq-default dotspacemacs-search-tools '("rg" "grep")) #+END_SRC Delete whitespace while saving buffer. Possible values are: @@ -1335,14 +1335,14 @@ Delete whitespace while saving buffer. Possible values are: - ~nil~ :: disable cleanup The default value is ~nil~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-whitespace-cleanup nil) +(setq-default dotspacemacs-whitespace-cleanup nil) #+END_SRC Set ~gc-cons-threshold~ and ~gc-cons-percentage~ when startup finishes. This is an advanced option and should not be changed unless you suspect performance issues due to garbage collection operations. The default is ~'(100000000 0.1)~ #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-gc-cons '(100000000 0.1)) +(setq-default dotspacemacs-gc-cons '(100000000 0.1)) #+END_SRC If non nil activate ~clean-aindent-mode~ which tries to correct virtual @@ -1350,7 +1350,7 @@ indentation of simple modes. This can interfer with mode specific indent handling like has been reported for ~go-mode~. If it does deactivate it here. Default ~t~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-use-clean-aindent-mode t) +(setq-default dotspacemacs-use-clean-aindent-mode t) #+END_SRC If non ~nil~, shift your number row to match the entered keyboard layout (only @@ -1358,14 +1358,14 @@ in insert state). Currently supported keyboard layouts are ~querty-us~, ~quertz-de~ and ~querty-ca-fr~. New layouts can be added in ~spacemacs-editing~ layer. Default ~nil~. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-swap-number-row nil) +(setq-default dotspacemacs-swap-number-row nil) #+END_SRC Set ~read-process-output-max~ when startup finishes. This defines how much data is read from a foreign process. Setting this >= 1 MB should increase performance for lsp servers in emacs 27. #+BEGIN_SRC emacs-lisp - (setq-default dotspacemacs-read-process-output-max (* 1024 1024 8)) +(setq-default dotspacemacs-read-process-output-max (* 1024 1024 8)) #+END_SRC * User Initialization @@ -1378,36 +1378,36 @@ for lsp servers in emacs 27. :CUSTOM_ID: User-Initialization-User-Init-a86829cf :END: #+BEGIN_SRC emacs-lisp :exports none - ;; -*- lexical-binding: t -*- +;; -*- lexical-binding: t -*- #+END_SRC While Emacs and especially Spacemacs loads, I want it to initialize some elements and load some packages. First of all, I want it to load my private Emacs config file: #+BEGIN_SRC emacs-lisp - (load "~/.emacs.spacemacs/private/private_emacs") +(load "~/.emacs.spacemacs/private/private_emacs") #+END_SRC I would also like to enable the setup of flycheck for Rust when Flycheck is loaded: #+BEGIN_SRC emacs-lisp - (add-hook 'flycheck-mode-hook #'flycheck-rust-setup) +(add-hook 'flycheck-mode-hook #'flycheck-rust-setup) #+END_SRC By default, Flyspell should be disabled and only enabled manually. #+BEGIN_SRC emacs-lisp - (flyspell-mode 0) +(flyspell-mode 0) #+END_SRC Finally, here is a quick workaround for Tramp, sometimes it cannot connect to my hosts if I don’t have this code snippet. #+BEGIN_SRC emacs-lisp - (setq tramp-ssh-controlmaster-options - "-o ControlMaster=auto -o ControlPath='tramp.%%C' -o ControlPersist=no") +(setq tramp-ssh-controlmaster-options + "-o ControlMaster=auto -o ControlPath='tramp.%%C' -o ControlPersist=no") #+END_SRC #+BEGIN_SRC emacs-lisp - (require 'org) +(require 'org) #+END_SRC ** User Load @@ -1417,12 +1417,12 @@ hosts if I don’t have this code snippet. :END: Then, I want a couple of requires: #+BEGIN_SRC emacs-lisp - (require 'org-id) - (require 'org-protocol) - (require 'package) - (require 'ox-latex) - (require 'ox-publish) - (require 'tramp) +(require 'org-id) +(require 'org-protocol) +(require 'package) +(require 'ox-latex) +(require 'ox-publish) +(require 'tramp) #+END_SRC * User Configuration @@ -1431,7 +1431,7 @@ Then, I want a couple of requires: :CUSTOM_ID: User_Configuration-4a937fe5 :END: #+BEGIN_SRC emacs-lisp :exports none - ;; -*- lexical-binding: t -*- +;; -*- lexical-binding: t -*- #+END_SRC ** Custom functions, macros, and variables :PROPERTIES: @@ -1482,14 +1482,14 @@ elements of the list ~seq~ against the predicate ~fn~ which should return either success, otherwise it is a failure. Note that empty lists will always return ~t~. #+BEGIN_SRC emacs-lisp - (defun phundrak-all? (fn seq) - "Check if all members of `SEQ' satisfy predicate `FN'. Note that - it will return t if `SEQ' is nil." - (declare (pure t) (side-effect-free t)) - (if seq - (and (funcall fn (car seq)) - (phundrak-all? fn (cdr seq))) - t)) +(defun phundrak-all? (fn seq) + "Check if all members of `SEQ' satisfy predicate `FN'. Note that +it will return t if `SEQ' is nil." + (declare (pure t) (side-effect-free t)) + (if seq + (and (funcall fn (car seq)) + (phundrak-all? fn (cdr seq))) + t)) #+END_SRC **** ~phundrak-none?~ @@ -1501,14 +1501,14 @@ In the same vein as ~phundrak-all?~, ~phundrak-none?~ checks if all elements of return ~t~. #+name: elisp-phundrak-none #+BEGIN_SRC emacs-lisp - (defun phundrak-none? (fn seq) - "Check if all members of `SEQ' do not satisfy predicate `FN'. - Note that it will return t if `SEQ' is nil." - (declare (pure t) (side-effect-free t)) - (if seq - (and (not (funcall fn (car seq))) - (phundrak-none? fn (cdr seq))) - t)) +(defun phundrak-none? (fn seq) + "Check if all members of `SEQ' do not satisfy predicate `FN'. +Note that it will return t if `SEQ' is nil." + (declare (pure t) (side-effect-free t)) + (if seq + (and (not (funcall fn (car seq))) + (phundrak-none? fn (cdr seq))) + t)) #+END_SRC **** ~phundrak-zip~ @@ -1517,18 +1517,17 @@ return ~t~. :END: #+name: elisp-phundrak-zip #+BEGIN_SRC emacs-lisp - (defun phundrak-zip (&rest lists) - "Zip `LISTS' together. - - Be aware only the amount of elements of the smallest list will be zipped." - (declare (pure t) (side-effect-free t)) - (when lists - (let ((lists (if (= 1 (length lists)) ; only one element => a list of lists was passed - (car lists) - lists))) - (when (phundrak-none? 'null lists) - (cons (mapcar 'car lists) - (phundrak-zip (mapcar 'cdr lists))))))) +(defun phundrak-zip (&rest lists) + "Zip `LISTS' together. +Be aware only the amount of elements of the smallest list will be zipped." + (declare (pure t) (side-effect-free t)) + (when lists + (let ((lists (if (= 1 (length lists)) ; only one element => a list of lists was passed + (car lists) + lists))) + (when (phundrak-none? 'null lists) + (cons (mapcar 'car lists) + (phundrak-zip (mapcar 'cdr lists))))))) #+END_SRC *** Eshell Prompt-Related Functions @@ -1546,70 +1545,70 @@ calls, the function will know what it needs to know about the repo to build a git prompt that will be inserted in my Eshell prompt. And just for shit and giggles, I’ve made it so it is a powerline prompt. #+BEGIN_SRC emacs-lisp - (defun phundrak-eshell-git-status ($path &optional $background-color) - "Returns a string indicating the status of the repository located - in `$PATH' if it exists. It should also append the name of the - current branch if it is not `master' or `main'. - `$BACKGROUND-COLOR' allows to choose the color that will be - visible behind the powerline characters. The theme is inspired by - the bobthefish theme for the fish shell which you can find here: - https://github.com/oh-my-fish/theme-bobthefish +(defun phundrak-eshell-git-status ($path &optional $background-color) + "Returns a string indicating the status of the repository located +in `$PATH' if it exists. It should also append the name of the +current branch if it is not `master' or `main'. +`$BACKGROUND-COLOR' allows to choose the color that will be +visible behind the powerline characters. The theme is inspired by +the bobthefish theme for the fish shell which you can find here: +https://github.com/oh-my-fish/theme-bobthefish - Color code: - - green: - - orange: tracked stuff is staged but not commited - - red: tracked stuff is modified and not commited +Color code: +- green: +- orange: tracked stuff is staged but not commited +- red: tracked stuff is modified and not commited - Symbols: - - `*': dirty working dir, RED - - `~': staged changes, ORANGE - - `…': untracked files, GREEN - - `$': stashed changes - - `-': unpulled commits - - `-': unpushed commits - - `±': unpulled and unpushed commits" - (let* ((git-status-command (concat "cd " $path "; git status")) - (git-stash-status-command (concat "cd " $path "; git stash list")) - (status (eshell-command-result git-status-command)) - (stashstat (eshell-command-result git-stash-status-command)) - (detached (s-contains? "HEAD detached" status)) - (dirty (s-contains? "Changes not staged for commit" status)) - (staged (s-contains? "Changes to be committed" status)) - (untracked (s-contains? "Untracked files" status)) - (pullable (s-contains? "git pull" status)) - (pushable (s-contains? "git push" status)) - (branch (replace-regexp-in-string "On Branch \\(.*\\)\n\\(.\\|\n\\)*" "\\1" status)) - (branch (unless (or (string= "master" branch) - (string= "main" branch) - detached) - branch))) - (let ((prompt (concat " " - (if detached ">" "") - (when branch (concat " " branch " ")) - (when dirty "*") - (when staged "~") - (when untracked "…") - (cond ((and pullable pushable) "±") - (pullable "-") - (pushable "+")) - (when stashstat "$") - " ")) - (accent (cond - (dirty phundrak-nord11) - (staged phundrak-nord13) - (t phundrak-nord14))) - (background (if $background-color - $background-color - phundrak-nord0))) - (concat (with-face "" - :background accent - :foreground background) - (with-face prompt - :background accent - :foreground (if dirty phundrak-nord6 background)) - (with-face "" - :background background - :foreground accent))))) +Symbols: +- `*': dirty working dir, RED +- `~': staged changes, ORANGE +- `…': untracked files, GREEN +- `$': stashed changes +- `-': unpulled commits +- `-': unpushed commits +- `±': unpulled and unpushed commits" + (let* ((git-status-command (concat "cd " $path "; git status")) + (git-stash-status-command (concat "cd " $path "; git stash list")) + (status (eshell-command-result git-status-command)) + (stashstat (eshell-command-result git-stash-status-command)) + (detached (s-contains? "HEAD detached" status)) + (dirty (s-contains? "Changes not staged for commit" status)) + (staged (s-contains? "Changes to be committed" status)) + (untracked (s-contains? "Untracked files" status)) + (pullable (s-contains? "git pull" status)) + (pushable (s-contains? "git push" status)) + (branch (replace-regexp-in-string "On Branch \\(.*\\)\n\\(.\\|\n\\)*" "\\1" status)) + (branch (unless (or (string= "master" branch) + (string= "main" branch) + detached) + branch))) + (let ((prompt (concat " " + (if detached ">" "") + (when branch (concat " " branch " ")) + (when dirty "*") + (when staged "~") + (when untracked "…") + (cond ((and pullable pushable) "±") + (pullable "-") + (pushable "+")) + (when stashstat "$") + " ")) + (accent (cond + (dirty phundrak-nord11) + (staged phundrak-nord13) + (t phundrak-nord14))) + (background (if $background-color + $background-color + phundrak-nord0))) + (concat (with-face "" + :background accent + :foreground background) + (with-face prompt + :background accent + :foreground (if dirty phundrak-nord6 background)) + (with-face "" + :background background + :foreground accent))))) #+END_SRC **** ~phundrak-git-repo-root~ @@ -1620,13 +1619,13 @@ This function detects if the path passed as an argument points to a git directory or to one of its subdirectories. If it is, it will return the path to the root of the git repository, else it will return ~nil~. #+BEGIN_SRC emacs-lisp - (defun phundrak-git-repo-root ($path) - "Return `$PATH' if it points to a git repository or one of its - subdirectories." - (when $path - (if (f-dir? (concat $path "/.git")) - $path - (phundrak-git-repo-root (f-parent $path))))) +(defun phundrak-git-repo-root ($path) + "Return `$PATH' if it points to a git repository or one of its +subdirectories." + (when $path + (if (f-dir? (concat $path "/.git")) + $path + (phundrak-git-repo-root (f-parent $path))))) #+END_SRC **** ~phundrak-prompt-toggle-abbreviation~ @@ -1634,15 +1633,15 @@ the root of the git repository, else it will return ~nil~. :CUSTOM_ID: User-Configuration-Custom-functions-macros-and-variables-phundrak-prompt-toggle-abbreviation-753ca549 :END: #+BEGIN_SRC emacs-lisp - (defvar phundrak-prompt--abbreviate t - "Whether or not to abbreviate the displayed path in the Eshell - prompt.") +(defvar phundrak-prompt--abbreviate t + "Whether or not to abbreviate the displayed path in the Eshell +prompt.") - (defun phundrak-prompt-toggle-abbreviation () - "Toggles whether the Eshell prompt should shorten the name of - the parent directories or not. See `phundrak-eshell-prompt'." - (interactive) - (setq phundrak-prompt--abbreviate (not phundrak-prompt--abbreviate))) +(defun phundrak-prompt-toggle-abbreviation () + "Toggles whether the Eshell prompt should shorten the name of +the parent directories or not. See `phundrak-eshell-prompt'." + (interactive) + (setq phundrak-prompt--abbreviate (not phundrak-prompt--abbreviate))) #+END_SRC **** ~phundrak-abbr-path~ @@ -1654,33 +1653,33 @@ the name of all the parent directories of the current one in its path, but leaves the current one written in full. It also abbreviates the equivalent of the ~$HOME~ (~/home//~) directory to a simple =~=. #+BEGIN_SRC emacs-lisp - (defun phundrak-abbr-path ($path &optional $abbreviate) - "Abbreviate `$PATH'. If `$ABBREVIATE' is t, then all parent - directories of the current directory will be abbreviated to one - letter only. If a parent directory is a hidden directory (i.e. - preceeded by a dot), the directory will be abbreviated to the dot - plus the first letter of the name of the directory (e.g. - \".config\" -> \".c\"). +(defun phundrak-abbr-path ($path &optional $abbreviate) + "Abbreviate `$PATH'. If `$ABBREVIATE' is t, then all parent +directories of the current directory will be abbreviated to one +letter only. If a parent directory is a hidden directory (i.e. +preceeded by a dot), the directory will be abbreviated to the dot +plus the first letter of the name of the directory (e.g. +\".config\" -> \".c\"). - For public use of the function, `$PATH' should be a string - representing a UNIX path. For internal use, `$PATH' can also be a - list. If `$PATH' is neither of those, an error will be thrown by - the function." - (cond - ((stringp $path) (f-short - (if $abbreviate - (phundrak-abbr-path (f-split (phundrak-abbr-path $path))) - $path))) - ((null $path) "") - ((listp $path) - (f-join (cond ((= 1 (length $path)) (car $path)) - (t (let* ((dir (car $path)) - (first-char (s-left 1 dir))) - (if (string= "." first-char) - (s-left 2 dir) - first-char)))) - (phundrak-abbr-path (cdr $path)))) - (t (error "Invalid argument %s, neither stringp nor listp" $path)))) +For public use of the function, `$PATH' should be a string +representing a UNIX path. For internal use, `$PATH' can also be a +list. If `$PATH' is neither of those, an error will be thrown by +the function." + (cond + ((stringp $path) (f-short + (if $abbreviate + (phundrak-abbr-path (f-split (phundrak-abbr-path $path))) + $path))) + ((null $path) "") + ((listp $path) + (f-join (cond ((= 1 (length $path)) (car $path)) + (t (let* ((dir (car $path)) + (first-char (s-left 1 dir))) + (if (string= "." first-char) + (s-left 2 dir) + first-char)))) + (phundrak-abbr-path (cdr $path)))) + (t (error "Invalid argument %s, neither stringp nor listp" $path)))) #+END_SRC *** Files-Related Functions @@ -1692,11 +1691,11 @@ the ~$HOME~ (~/home//~) directory to a simple =~=. :CUSTOM_ID: User-Configuration-Custom-functions-macros-and-variables-phundrak-file-to-string-efab0fba :END: #+BEGIN_SRC emacs-lisp - (defun phundrak-file-to-string (FILE) - "Returns the content of `FILE' as a string." - (with-temp-buffer - (insert-file-contents FILE) - (buffer-string))) +(defun phundrak-file-to-string (FILE) + "Returns the content of `FILE' as a string." + (with-temp-buffer + (insert-file-contents FILE) + (buffer-string))) #+END_SRC **** ~phundrak-find-org-files~ @@ -1711,11 +1710,11 @@ conlanging files which are located in =~/Documents/conlanging=, and all my university notes are in =~/Documents/university=. Let’s declare these directories in a variable: #+BEGIN_SRC emacs-lisp - (defvar phundrak-org-directories '("~/org" - "~/Documents/university/S8" - "~/Documents/conlanging") - "Directories in which to look for org files with the function - `phundrak-find-org-files'.") +(defvar phundrak-org-directories '("~/org" + "~/Documents/university/S8" + "~/Documents/conlanging") + "Directories in which to look for org files with the function +`phundrak-find-org-files'.") #+END_SRC With this established, let’s write some emacs-lisp that will allow me to get a @@ -1723,20 +1722,20 @@ list of all these files and select them through helm. Be aware that I will be using some functions from third party packages, such as [[https://github.com/magnars/s.el][s.el]] and [[https://github.com/magnars/dash.el][dash]], as well as [[https://github.com/sharkdp/fd][fd]]. #+BEGIN_SRC emacs-lisp - (defun phundrak-find-org-files () - "Find all org files in the directories listed in - `phundrak-org-directories', then list them in an ido buffer where - the user can match one and open it." - (interactive) - (find-file - (ivy-completing-read - "Org File: " - (s-split "\n" - (mapconcat (lambda (path) - (shell-command-to-string - (format "fd . %s -e org -c never" path))) - phundrak-org-directories - "\n"))))) +(defun phundrak-find-org-files () + "Find all org files in the directories listed in +`phundrak-org-directories', then list them in an ido buffer where +the user can match one and open it." + (interactive) + (find-file + (ivy-completing-read + "Org File: " + (s-split "\n" + (mapconcat (lambda (path) + (shell-command-to-string + (format "fd . %s -e org -c never" path))) + phundrak-org-directories + "\n"))))) #+END_SRC **** ~phundrak-open-marked-files~ @@ -1747,16 +1746,16 @@ This function is particularly useful in Dired buffers when someone wants to open multiple files. This function will basically look for all marked files in the current dired buffer and open each one of them in their individual buffer. #+BEGIN_SRC emacs-lisp - (defun phundrak-open-marked-files () - "This function allows the user to open all marked files in a - Dired buffer at once." - (interactive) - (let ((file-list (if (string= major-mode "dired-mode") - (dired-get-marked-files) - (list (buffer-file-name))))) - (mapc (lambda (file) - (find-file file)) - file-list))) +(defun phundrak-open-marked-files () + "This function allows the user to open all marked files in a +Dired buffer at once." + (interactive) + (let ((file-list (if (string= major-mode "dired-mode") + (dired-get-marked-files) + (list (buffer-file-name))))) + (mapc (lambda (file) + (find-file file)) + file-list))) #+END_SRC **** ~xah/open-in-external-app~ @@ -1767,28 +1766,28 @@ Here is another of Xah’s functions, this time to open a file externally to Emacs. For instance, I sometimes want to open a PDF in Zathura rather than in Emacs, or an HTML file in Firefox. With this function, it is now possible! #+BEGIN_SRC emacs-lisp - (defun xah/open-in-external-app (&optional files) - "Open the current file or dired marked files in external app. - The app is chosen from your OS’ preference. +(defun xah/open-in-external-app (&optional files) + "Open the current file or dired marked files in external app. +The app is chosen from your OS’ preference. - When called in emacs lisp, if `FILES' is given, open that. +When called in emacs lisp, if `FILES' is given, open that. - URL `http://ergoemacs.org/emacs/emacs_dired_open_file_in_ext_apps.html' - Version 2019-01-18" - (interactive) - (let* (($file-list (if files - (progn (list files)) - (if (string-equal major-mode "dired-mode") - (dired-get-marked-files) - (list (buffer-file-name))))) - ($do-it-p (if (<= (length $file-list) 5) - t - (y-or-n-p "Open more than 5 files? ")))) - (when $do-it-p - (mapc (lambda ($fpath) - (let ((process-connection-type nil)) - (start-process "" nil "xdg-open" $fpath))) - $file-list)))) +URL `http://ergoemacs.org/emacs/emacs_dired_open_file_in_ext_apps.html' +Version 2019-01-18" + (interactive) + (let* (($file-list (if files + (progn (list files)) + (if (string-equal major-mode "dired-mode") + (dired-get-marked-files) + (list (buffer-file-name))))) + ($do-it-p (if (<= (length $file-list) 5) + t + (y-or-n-p "Open more than 5 files? ")))) + (when $do-it-p + (mapc (lambda ($fpath) + (let ((process-connection-type nil)) + (start-process "" nil "xdg-open" $fpath))) + $file-list)))) #+END_SRC *** Theming @@ -1802,22 +1801,22 @@ Emacs, or an HTML file in Firefox. With this function, it is now possible! Yes, I do use a preconfigured theme, as mentioned above, but for some elements such as Eshell, I need to define some variables for color, and I’ll do it here. #+BEGIN_SRC emacs-lisp - (defvar phundrak-nord0 "#2e3440") - (defvar phundrak-nord1 "#3b4252") - (defvar phundrak-nord2 "#434c5e") - (defvar phundrak-nord3 "#4c566a") - (defvar phundrak-nord4 "#d8dee9") - (defvar phundrak-nord5 "#e5e9f0") - (defvar phundrak-nord6 "#eceff4") - (defvar phundrak-nord7 "#8fbcbb") - (defvar phundrak-nord8 "#88c0d0") - (defvar phundrak-nord9 "#81a1c1") - (defvar phundrak-nord10 "#5e81ac") - (defvar phundrak-nord11 "#bf616a") - (defvar phundrak-nord12 "#d08770") - (defvar phundrak-nord13 "#ebcb8b") - (defvar phundrak-nord14 "#a3be8c") - (defvar phundrak-nord15 "#b48ead") +(defvar phundrak-nord0 "#2e3440") +(defvar phundrak-nord1 "#3b4252") +(defvar phundrak-nord2 "#434c5e") +(defvar phundrak-nord3 "#4c566a") +(defvar phundrak-nord4 "#d8dee9") +(defvar phundrak-nord5 "#e5e9f0") +(defvar phundrak-nord6 "#eceff4") +(defvar phundrak-nord7 "#8fbcbb") +(defvar phundrak-nord8 "#88c0d0") +(defvar phundrak-nord9 "#81a1c1") +(defvar phundrak-nord10 "#5e81ac") +(defvar phundrak-nord11 "#bf616a") +(defvar phundrak-nord12 "#d08770") +(defvar phundrak-nord13 "#ebcb8b") +(defvar phundrak-nord14 "#a3be8c") +(defvar phundrak-nord15 "#b48ead") #+END_SRC **** ~with-face~ @@ -1828,9 +1827,9 @@ such as Eshell, I need to define some variables for color, and I’ll do it here strings with faces defined as properties to the string passed as the first argument. Here is how it is implemented: #+BEGIN_SRC emacs-lisp - (defmacro with-face ($str &rest $properties) - "Helper macro for creating strings `$STR' with `$PROPERTIES'" - `(propertize ,$str 'face (list ,@$properties))) +(defmacro with-face ($str &rest $properties) + "Helper macro for creating strings `$STR' with `$PROPERTIES'" + `(propertize ,$str 'face (list ,@$properties))) #+END_SRC *** ~phundrak-blog-publish~ @@ -1842,20 +1841,20 @@ based on Hugo. After exporting my blog using ~ox-hugo~, I simply have to call this function which will look for all files located in =~/org/blog/public= and copy them to my remote server once ~hugo~ has been executed in =~/org/blog=. #+BEGIN_SRC emacs-lisp - (defun phundrak-blog-publish () - "Publish my blog through Hugo and rsync to my remote server." - (interactive) - (let* ((blog-path "~/org/blog") - (public-path (concat blog-path "/public")) - (target-path "/rsync:Tilo:/home/phundrak/www/phundrak.com/blog")) - (shell-command (format "cd %s && hugo" blog-path)) - (let ((files (mapcar (lambda (file) - (f-relative file public-path)) - (f-files (format "%s/public" blog-path) nil t)))) - (dolist (file files) - (copy-file (concat public-path "/" file) - (concat target-path "/" file) - t nil t))))) +(defun phundrak-blog-publish () + "Publish my blog through Hugo and rsync to my remote server." + (interactive) + (let* ((blog-path "~/org/blog") + (public-path (concat blog-path "/public")) + (target-path "/rsync:Tilo:/home/phundrak/www/phundrak.com/blog")) + (shell-command (format "cd %s && hugo" blog-path)) + (let ((files (mapcar (lambda (file) + (f-relative file public-path)) + (f-files (format "%s/public" blog-path) nil t)))) + (dolist (file files) + (copy-file (concat public-path "/" file) + (concat target-path "/" file) + t nil t))))) #+END_SRC *** ~phundrak-yas-rust-new-assignments~ @@ -1868,27 +1867,26 @@ function, it will automatically write assignments to my new struct as I write new parameters in the ~new~ function. It also comes with a helper function that parses the arguments given to the ~new~ function. #+BEGIN_SRC emacs-lisp - (defun phundrak--yas-snippet-split-rust-args ($arg-string) - "Split a Rust argument string `$ARG-STRING' into ((name, - default)...) tuples" - (mapcar (lambda ($elem) - (split-string $elem "[[:blank:]]*:[[:blank:]]*" t)) - (split-string $arg-string "[[:blank:]]*,[[:blank:]]*" t))) +(defun phundrak--yas-snippet-split-rust-args ($arg-string) + "Split a Rust argument string `$ARG-STRING' into ((name, +default)...) tuples" + (mapcar (lambda ($elem) + (split-string $elem "[[:blank:]]*:[[:blank:]]*" t)) + (split-string $arg-string "[[:blank:]]*,[[:blank:]]*" t))) - (defun phundrak-yas-rust-new-assignments ($arg-string) - "Return a typical new assignment for arguments. - - Inspired from elpy’s functions https://github.com/jorgenschaefer/elpy" - (let ((indentation (make-string (save-excursion - (goto-char start-point) - (current-indentation)) - ?\s))) - (mapconcat (lambda ($elem) - (if (string-match "^\\*" (car $elem)) - "" - (format "%s,\n%s" (car $elem) indentation))) - (phundrak--yas-snippet-split-rust-args $arg-string) - ""))) +(defun phundrak-yas-rust-new-assignments ($arg-string) + "Return a typical new assignment for arguments. +Inspired from elpy’s functions https://github.com/jorgenschaefer/elpy" + (let ((indentation (make-string (save-excursion + (goto-char start-point) + (current-indentation)) + ?\s))) + (mapconcat (lambda ($elem) + (if (string-match "^\\*" (car $elem)) + "" + (format "%s,\n%s" (car $elem) indentation))) + (phundrak--yas-snippet-split-rust-args $arg-string) + ""))) #+END_SRC *** ~screenshot-svg~ @@ -1898,16 +1896,16 @@ parses the arguments given to the ~new~ function. This function allows for taking SVG screenshots of Emacs from itself using Cairo. The function definition was taken [[https://github.com/caiohcs/my-emacs#screenshots][from here]]. #+BEGIN_SRC emacs-lisp - (defun screenshot-svg () - "Save a screenshot of the current frame as an SVG image. - Saves to a temp file and puts the filename in the kill ring." - (interactive) - (let* ((filename (make-temp-file "Emacs" nil ".svg")) - (data (x-export-frames nil 'svg))) - (with-temp-file filename - (insert data)) - (kill-new filename) - (message filename))) +(defun screenshot-svg () + "Save a screenshot of the current frame as an SVG image. +Saves to a temp file and puts the filename in the kill ring." + (interactive) + (let* ((filename (make-temp-file "Emacs" nil ".svg")) + (data (x-export-frames nil 'svg))) + (with-temp-file filename + (insert data)) + (kill-new filename) + (message filename))) #+END_SRC *** ~xah/dired-sort~ @@ -1921,20 +1919,20 @@ files in a dired buffer depending on four factors: - Last modification date - File extension #+BEGIN_SRC emacs-lisp - (defun xah/dired-sort () - "Sort dired dir listing in different ways. Prompt for a choice. - URL `http://ergoemacs.org/emacs/dired_sort.html' - Version 2018-12-23, modified by Phundrak on 2019-08-06" - (interactive) - (let ($sort-by $arg) - (setq $sort-by (ido-completing-read "Sort by:" '( "name" "size" "date" "extension" ))) - (cond - ((equal $sort-by "name") (setq $arg "-ahl --group-directories-first")) - ((equal $sort-by "date") (setq $arg "-ahl -t --group-directories-first")) - ((equal $sort-by "size") (setq $arg "-ahl -S --group-directories-first")) - ((equal $sort-by "extension") (setq $arg "-ahlD -X --group-directories-first")) - (t (error "logic error 09535" ))) - (dired-sort-other $arg ))) +(defun xah/dired-sort () + "Sort dired dir listing in different ways. Prompt for a choice. +URL `http://ergoemacs.org/emacs/dired_sort.html' +Version 2018-12-23, modified by Phundrak on 2019-08-06" + (interactive) + (let ($sort-by $arg) + (setq $sort-by (ido-completing-read "Sort by:" '( "name" "size" "date" "extension" ))) + (cond + ((equal $sort-by "name") (setq $arg "-ahl --group-directories-first")) + ((equal $sort-by "date") (setq $arg "-ahl -t --group-directories-first")) + ((equal $sort-by "size") (setq $arg "-ahl -S --group-directories-first")) + ((equal $sort-by "extension") (setq $arg "-ahlD -X --group-directories-first")) + (t (error "logic error 09535" ))) + (dired-sort-other $arg ))) #+END_SRC ** Editing and modes @@ -1947,7 +1945,7 @@ through words that are in CamelCase more easily, I don’t have to go either to the beginning or the end of the word and then move my cursor a bunch of times to get to the subword I want to modify. #+BEGIN_SRC emacs-lisp - (global-subword-mode 1) +(global-subword-mode 1) #+END_SRC *** Default modes @@ -1958,7 +1956,7 @@ Some buffers sometimes won’t have a default mode at all, such as the ~*scratch buffer. In any vanilla configuration, they will then default to ~text-mode~. I personally prefer ~org-mode~ to be my default mode, so let’s set it so! #+BEGIN_SRC emacs-lisp - (setq edit-server-default-major-mode 'org-mode) +(setq edit-server-default-major-mode 'org-mode) #+END_SRC *** Evil @@ -1977,8 +1975,8 @@ undo action more granular, but it comes at the cost of increasing the amount of undo actions you can do (which shouldn’t really matter if you don’t have a potato PC). #+BEGIN_SRC emacs-lisp - (setq undo-limit 500000 - evil-want-fine-undo t) +(setq undo-limit 500000 + evil-want-fine-undo t) #+END_SRC *** File extensions @@ -1989,32 +1987,32 @@ Sometimes, Emacs doesn’t recognize or misrecognizes some extensions, resulting in a wrong mode set for said file. Let’s fix that by associating the extension with the desired mode: #+BEGIN_SRC emacs-lisp - (dolist (e '(("xml" . web-mode) - ("xinp" . web-mode) - ("aiml" . web-mode) - ("C" . c++-mode) - ("dconf" . conf-mode) - ("yy" . bison-mode) - ("ll" . flex-mode) - ("s" . asm-mode) - ("pl" . prolog-mode) - ("l" . scheme-mode) - ("vs" . glsl-mode) - ("fs" . glsl-mode))) - (push (cons (concat "\\." - (car e) - "\\'") (cdr e)) - auto-mode-alist)) +(dolist (e '(("xml" . web-mode) + ("xinp" . web-mode) + ("aiml" . web-mode) + ("C" . c++-mode) + ("dconf" . conf-mode) + ("yy" . bison-mode) + ("ll" . flex-mode) + ("s" . asm-mode) + ("pl" . prolog-mode) + ("l" . scheme-mode) + ("vs" . glsl-mode) + ("fs" . glsl-mode))) + (push (cons (concat "\\." + (car e) + "\\'") (cdr e)) + auto-mode-alist)) #+END_SRC We also have a couple of extensions which should all be in ~conf-unix-mode~, let’s indicate that to Emacs: #+BEGIN_SRC emacs-lisp - (dolist (e '("service" "timer" "target" "mount" "automount" - "slice" "socket" "path" "netdev" "network" - "link")) - (push (cons (concat "\\." e "\\'") 'conf-unix-mode) - auto-mode-alist)) +(dolist (e '("service" "timer" "target" "mount" "automount" + "slice" "socket" "path" "netdev" "network" + "link")) + (push (cons (concat "\\." e "\\'") 'conf-unix-mode) + auto-mode-alist)) #+END_SRC *** Hooks @@ -2025,26 +2023,26 @@ I also have some hooks I use for enabling some major and minor modes. The first one here allows the execution of the deletion of trailing space each time I save a file. #+BEGIN_SRC emacs-lisp - (add-hook 'before-save-hook 'delete-trailing-whitespace) +(add-hook 'before-save-hook 'delete-trailing-whitespace) #+END_SRC I also want to always be in ~visual-line-mode~ so Emacs soft-wraps lines that are too long for the buffer they are displayed in. This will also be enabled for Elfeed. #+BEGIN_SRC emacs-lisp - (add-hook 'prog-mode-hook 'visual-line-mode) - (add-hook 'elfeed-read-mode-hook 'visual-line-mode) +(add-hook 'prog-mode-hook 'visual-line-mode) +(add-hook 'elfeed-read-mode-hook 'visual-line-mode) #+END_SRC I also want for some non-programming modes to enable a hard-limit in terms of how many characters can fit on one line. The modes that benefit are ~message-mode~, ~org-mode~, ~text-mode~ and ~markdown-mode~. #+BEGIN_SRC emacs-lisp - (mapc (lambda (x) - (add-hook x 'visual-line-mode)) - '(message-mode-hook - text-mode-hook - markdown-mode-hook)) +(mapc (lambda (x) + (add-hook x 'visual-line-mode)) + '(message-mode-hook + text-mode-hook + markdown-mode-hook)) #+END_SRC *** Twittering mode @@ -2054,7 +2052,7 @@ how many characters can fit on one line. The modes that benefit are For ~twittering-mode~, a Twitter major mode for Emacs, I want to encrypt my data using a master password, which I do thanks to this option: #+BEGIN_SRC emacs-lisp - (setq twittering-use-master-password t) +(setq twittering-use-master-password t) #+END_SRC *** Wrapping regions @@ -2065,12 +2063,12 @@ I really like the ~M-(~ keybinding for wrapping a selected region between parenthesis. However, parenthesis are not everything (even in Lisp dialects), and other wrappers could be nice. And they are! Here is how they are declared: #+BEGIN_SRC emacs-lisp - (global-set-key (kbd "M-[") 'insert-pair) - (global-set-key (kbd "M-{") 'insert-pair) - (global-set-key (kbd "M-<") 'insert-pair) - (global-set-key (kbd "M-'") 'insert-pair) - (global-set-key (kbd "M-`") 'insert-pair) - (global-set-key (kbd "M-\"") 'insert-pair) +(global-set-key (kbd "M-[") 'insert-pair) +(global-set-key (kbd "M-{") 'insert-pair) +(global-set-key (kbd "M-<") 'insert-pair) +(global-set-key (kbd "M-'") 'insert-pair) +(global-set-key (kbd "M-`") 'insert-pair) +(global-set-key (kbd "M-\"") 'insert-pair) #+END_SRC For the record, this is from [[http://www.howardism.org/][Howard Abram]]’s [[https://github.com/howardabrams/dot-files][dotfiles]]. @@ -2087,31 +2085,31 @@ When it comes to dired, I chose do modify some elements on how things are sorted and shown, but there isn’t much configuration. First, I want to always copy folders in a recursive way, no questions asked. #+BEGIN_SRC emacs-lisp - (setq dired-recursive-copies 'always) +(setq dired-recursive-copies 'always) #+END_SRC Also, when I have two Dired buffers opened side by side, I generally want them to interact with each other, for example if I want to move around or copy stuff. So, let’s tell Emacs that: #+BEGIN_SRC emacs-lisp - (setq dired-dwim-target t) +(setq dired-dwim-target t) #+END_SRC Finally, let’s tell Dired how to sort the elements to be displayed: directories first, non-hidden first. #+BEGIN_SRC emacs-lisp - (setq dired-listing-switches "-ahl --group-directories-first") +(setq dired-listing-switches "-ahl --group-directories-first") #+END_SRC By the way, let’s enable ~org-download~ when we are in a Dired buffer: #+BEGIN_SRC emacs-lisp - (add-hook 'dired-mode-hook 'org-download-enable) +(add-hook 'dired-mode-hook 'org-download-enable) #+END_SRC Finally, let’s enable globally ~diredfl~ so we can get a colourful Dired buffer each time we open one: #+BEGIN_SRC emacs-lisp - (diredfl-global-mode 1) +(diredfl-global-mode 1) #+END_SRC *** Emacs Lisp @@ -2121,7 +2119,7 @@ each time we open one: For some reason, =flycheck-mode= is not enabled by default when in an elisp buffer. Let’s add that: #+BEGIN_SRC emacs-lisp - (add-hook 'emacs-lisp-mode-hook 'flycheck-mode) +(add-hook 'emacs-lisp-mode-hook 'flycheck-mode) #+END_SRC *** Eshell @@ -2144,39 +2142,39 @@ This function is a function that will come in very handy for Eshell functions that call shell processes. It concatenates the initial string ~command~ with all the arguments ~args~, each separated with a space. #+BEGIN_SRC emacs-lisp - (defun phundrak/concatenate-shell-command ($command &rest $args) - (string-join (cons $command $args) " ")) +(defun phundrak/concatenate-shell-command ($command &rest $args) + (string-join (cons $command $args) " ")) #+END_SRC Just like most shells, it is possible to declare in Eshell aliases. First, I would like to be able to use ~open~ to open files in Emacs: #+BEGIN_SRC emacs-lisp - (defalias 'open 'find-file) +(defalias 'open 'find-file) #+END_SRC I also have ~openo~ which allows me to perform the same action, but in another window: #+BEGIN_SRC emacs-lisp - (defalias 'openo 'find-file-other-window) +(defalias 'openo 'find-file-other-window) #+END_SRC The function ~yes-or-no-p~ is also aliased to ~y-or-n-p~ so I only have to answer by ~y~ or ~n~ instead of typing ~yes~ or ~no~. #+BEGIN_SRC emacs-lisp - (defalias 'yes-or-no-p 'y-or-n-p) +(defalias 'yes-or-no-p 'y-or-n-p) #+END_SRC For some ease of use, I’ll also declare ~list-buffers~ as an alias of ~ibuffer~. #+BEGIN_SRC emacs-lisp - (defalias 'list-buffers 'ibuffer) +(defalias 'list-buffers 'ibuffer) #+END_SRC ~mkcd~ is a function that allows me to create a directory and ~cd~ into it at the same time. #+begin_src emacs-lisp - (defun eshell/mkcd ($directory) - (eshell/mkdir "-p" $directory) - (cd $directory)) +(defun eshell/mkcd ($directory) + (eshell/mkdir "-p" $directory) + (cd $directory)) #+end_src **** Custom functions @@ -2187,20 +2185,20 @@ When I’m in Eshell, sometimes I wish to open multiple files at once in Emacs. For this, when I have several arguments for ~find-file~, I want to be able to open them all at once. Let’s modify ~find-file~ like so: #+BEGIN_SRC emacs-lisp - (defadvice find-file (around find-files activate) - "Also find all files within a list of files. This even works recursively." - (if (listp filename) - (cl-loop for f in filename do (find-file f wildcards)) - ad-do-it)) +(defadvice find-file (around find-files activate) + "Also find all files within a list of files. This even works recursively." + (if (listp filename) + (cl-loop for f in filename do (find-file f wildcards)) + ad-do-it)) #+END_SRC I also want to be able to have multiple instances of Eshell opened at once. For that, I declared the function ~eshell-new~ that does exactly that. #+BEGIN_SRC emacs-lisp - (defun eshell-new() - "Open a new instance of eshell." - (interactive) - (eshell 'N)) +(defun eshell-new() + "Open a new instance of eshell." + (interactive) + (eshell 'N)) #+END_SRC ***** Redirect text editors to Emacs @@ -2212,13 +2210,13 @@ terminal, which is stupid with Eshell since I’m already inside Emacs. So, let open each file passed to the ~emacs~ command and bury the eshell buffer (we’ll get back to it later). #+BEGIN_SRC emacs-lisp - (defun eshell/emacs (&rest $files) - "Open a file in a new buffer. Old habits die hard" - (if $files - (mapc #'find-file - (mapcar #'expand-file-name - (eshell-flatten-list (reverse $files)))) - (bury-buffer))) +(defun eshell/emacs (&rest $files) + "Open a file in a new buffer. Old habits die hard" + (if $files + (mapc #'find-file + (mapcar #'expand-file-name + (eshell-flatten-list (reverse $files)))) + (bury-buffer))) #+END_SRC **** Environment variables @@ -2229,38 +2227,38 @@ Some environment variables need to be correctly set so Eshell can correctly work. The first environment variable to be set is the ~PATH~, as I have a couple of directories where executables are located. Let’s add them to our path. #+BEGIN_SRC emacs-lisp - (setenv "PATH" - (concat - (getenv "HOME") "/.pub-cache/bin" - ":" (getenv "HOME") "/.local/bin" - ":" (getenv "HOME") "/go/bin" - ":" (getenv "HOME") "/.cargo/bin" - ":" (getenv "HOME") "/.gem/ruby/2.6.0/bin" - ":" (getenv "PATH"))) +(setenv "PATH" + (concat + (getenv "HOME") "/.pub-cache/bin" + ":" (getenv "HOME") "/.local/bin" + ":" (getenv "HOME") "/go/bin" + ":" (getenv "HOME") "/.cargo/bin" + ":" (getenv "HOME") "/.gem/ruby/2.6.0/bin" + ":" (getenv "PATH"))) #+END_SRC I would also like to set two environment variables related to Dart development: the ~DART_SDK~ and ~ANDROID_HOME~ variables. #+BEGIN_SRC emacs-lisp - (setenv "DART_SDK" "/opt/dart-sdk/bin") - (setenv "ANDROID_HOME" (concat (getenv "HOME") "/Android/Sdk/")) +(setenv "DART_SDK" "/opt/dart-sdk/bin") +(setenv "ANDROID_HOME" (concat (getenv "HOME") "/Android/Sdk/")) #+END_SRC Finally, I’d like to add a custom directory to the ~PKG_CONFIG_PATH~: #+BEGIN_SRC emacs-lisp - (setenv "PKG_CONFIG_PATH" (concat - "/usr/local/lib/pkgconfig/" ":" - (getenv "PKG_CONFIG_PATH"))) +(setenv "PKG_CONFIG_PATH" (concat + "/usr/local/lib/pkgconfig/" ":" + (getenv "PKG_CONFIG_PATH"))) #+END_SRC The ~EDITOR~ variable also needs to be set for git commands, especially the ~yadm~ commands. #+BEGIN_SRC emacs-lisp - (setenv "EDITOR" "emacsclient -c") +(setenv "EDITOR" "emacsclient -c") #+END_SRC #+BEGIN_SRC emacs-lisp - (setenv "SHELL" "/bin/sh") +(setenv "SHELL" "/bin/sh") #+END_SRC **** Eshell banner @@ -2283,16 +2281,16 @@ Some of these information can be grabbed directly from Emacs built-in functions, but some others need to be retrieved manually. Let’s first get into it with the mounted partitions for which we’ll define a structure: #+BEGIN_SRC emacs-lisp - (cl-defstruct phundrak/mounted-partitions - "Object representing a mounted partition found in the system" - path size used percent) +(cl-defstruct phundrak/mounted-partitions + "Object representing a mounted partition found in the system" + path size used percent) #+END_SRC We’ll also define a variable setting the maximum length of a partition path before it gets abbreviated: #+BEGIN_SRC emacs-lisp - (defvar phundrak//eshell-banner--max-length-part 13 - "Maximum length of a partition path") +(defvar phundrak//eshell-banner--max-length-part 13 + "Maximum length of a partition path") #+END_SRC Now, we can get our partitions. For this, we’ll make a call to the shell command @@ -2302,26 +2300,26 @@ the partition exceeds the length specified by ~phundrak//eshell-banner--max-length-part~, it will get abbreviated by [[#User-Configuration-Custom-functions-macros-and-variables-phundrak-abbr-path-559b46e3][~phundrak-abbr-path~]]. #+BEGIN_SRC emacs-lisp - (defun phundrak/get-mounted-partitions () - (let ((partitions (s-split "\n" - (shell-command-to-string "df -lH") - t))) - (-keep (lambda (partition) - (let* ((partition (s-split " " partition t)) - (filesystem (nth 0 partition)) - (size (nth 1 partition)) - (used (nth 2 partition)) - (percent (nth 4 partition)) - (mount (nth 5 partition))) - (when (s-prefix? "/dev" filesystem) - (make-phundrak/mounted-partitions - :path (if (> phundrak//eshell-banner--max-length-part (length mount)) - mount - (phundrak-abbr-path mount t)) - :size size - :used used - :percent (string-to-number (s-chop-suffix "%" percent)))))) - partitions))) +(defun phundrak/get-mounted-partitions () + (let ((partitions (s-split "\n" + (shell-command-to-string "df -lH") + t))) + (-keep (lambda (partition) + (let* ((partition (s-split " " partition t)) + (filesystem (nth 0 partition)) + (size (nth 1 partition)) + (used (nth 2 partition)) + (percent (nth 4 partition)) + (mount (nth 5 partition))) + (when (s-prefix? "/dev" filesystem) + (make-phundrak/mounted-partitions + :path (if (> phundrak//eshell-banner--max-length-part (length mount)) + mount + (phundrak-abbr-path mount t)) + :size size + :used used + :percent (string-to-number (s-chop-suffix "%" percent)))))) + partitions))) #+END_SRC We’ll need some padding for the name of the information displayed on the left @@ -2329,14 +2327,14 @@ hand side of the banner. The maximum length without any partitions is eight characters due to the text ~Hostname~, so if any partition path is longer than this, the left padding will increase. #+BEGIN_SRC emacs-lisp - (defun phundrak//eshell-banner--get-left-pad (initial-pad partitions) - (if partitions - (let ((part-length (length (phundrak/mounted-partitions-path (car partitions))))) - (phundrak//eshell-banner--get-left-pad (if (> part-length initial-pad) - part-length - initial-pad) - (cdr partitions))) - initial-pad)) +(defun phundrak//eshell-banner--get-left-pad (initial-pad partitions) + (if partitions + (let ((part-length (length (phundrak/mounted-partitions-path (car partitions))))) + (phundrak//eshell-banner--get-left-pad (if (> part-length initial-pad) + part-length + initial-pad) + (cdr partitions))) + initial-pad)) #+END_SRC Now, Let’s set three variables that will be used in the function following this @@ -2348,20 +2346,20 @@ and it should be watched and displayed in yellow. Above 75%, the user should consider this a warning, and the percentage will be displayed in orange. Above 90%, it is considered critical and the percentage will be displayed in red. #+BEGIN_SRC emacs-lisp - (defvar phundrak//eshell-banner--critical-percentage 90) - (defvar phundrak//eshell-banner--warning-percentage 75) - (defvar phundrak//eshell-banner--notice-percentage 60) +(defvar phundrak//eshell-banner--critical-percentage 90) +(defvar phundrak//eshell-banner--warning-percentage 75) +(defvar phundrak//eshell-banner--notice-percentage 60) - (defun phundrak//eshell-banner--color-percentage (percentage) - (cond - ((> percentage phundrak//eshell-banner--critical-percentage) - (with-face (format "%2d" percentage) :foreground phundrak-nord11)) - ((> percentage phundrak//eshell-banner--warning-percentage) - (with-face (format "%2d" percentage) :foreground phundrak-nord12)) - ((> percentage phundrak//eshell-banner--notice-percentage) - (with-face (format "%2d" percentage) :foreground phundrak-nord13)) - (t - (with-face (format "%2d" percentage) :foreground phundrak-nord14)))) +(defun phundrak//eshell-banner--color-percentage (percentage) + (cond + ((> percentage phundrak//eshell-banner--critical-percentage) + (with-face (format "%2d" percentage) :foreground phundrak-nord11)) + ((> percentage phundrak//eshell-banner--warning-percentage) + (with-face (format "%2d" percentage) :foreground phundrak-nord12)) + ((> percentage phundrak//eshell-banner--notice-percentage) + (with-face (format "%2d" percentage) :foreground phundrak-nord13)) + (t + (with-face (format "%2d" percentage) :foreground phundrak-nord14)))) #+END_SRC This function will be used when displaying progress bars. These will be used for @@ -2370,17 +2368,17 @@ part in red and the free part in green. For this, we just need to know the size of the progress bar we wish to use as well as how full it should be. Note that the percentage should be between 0 and 100. #+BEGIN_SRC emacs-lisp - (defun phundrak//eshell-banner--progress-bar (length percentage) - (let* ((length-green (if (= 0 percentage) - 0 - (/ (* length percentage) 100))) - (length-red (- length length-green))) - (concat (with-face "[" :weight 'bold) - (with-face (s-repeat length-green "=") - :weight 'bold :foreground phundrak-nord14) - (with-face (s-repeat length-red "=") - :weight 'bold :foreground phundrak-nord11) - (with-face "]" :weight 'bold)))) +(defun phundrak//eshell-banner--progress-bar (length percentage) + (let* ((length-green (if (= 0 percentage) + 0 + (/ (* length percentage) 100))) + (length-red (- length length-green))) + (concat (with-face "[" :weight 'bold) + (with-face (s-repeat length-green "=") + :weight 'bold :foreground phundrak-nord14) + (with-face (s-repeat length-red "=") + :weight 'bold :foreground phundrak-nord11) + (with-face "]" :weight 'bold)))) #+END_SRC This function will be used in two distinct functions: ~phundrak-eshell-banner~ @@ -2388,98 +2386,98 @@ which we will see later, and ~phundrak//eshell-banner--display-memory~ which we will see now. This function displays information for the two types of memory we have, RAM and Swap memory. Here is the definition of this function: #+BEGIN_SRC emacs-lisp - (defun phundrak//eshell-banner--display-memory (type used total text-padding ramp-length) - (let ((percentage (if (= used 0) - 0 - (/ (* 100 used) total)))) - (concat (s-pad-right text-padding "." type) - ": " - (phundrak//eshell-banner--progress-bar ramp-length - percentage) - (format " %6s / %-5s (" - (file-size-human-readable used) - (file-size-human-readable total)) - (phundrak//eshell-banner--color-percentage - percentage) - "%)\n"))) +(defun phundrak//eshell-banner--display-memory (type used total text-padding ramp-length) + (let ((percentage (if (= used 0) + 0 + (/ (* 100 used) total)))) + (concat (s-pad-right text-padding "." type) + ": " + (phundrak//eshell-banner--progress-bar ramp-length + percentage) + (format " %6s / %-5s (" + (file-size-human-readable used) + (file-size-human-readable total)) + (phundrak//eshell-banner--color-percentage + percentage) + "%)\n"))) #+END_SRC We now need a function for displaying partitions. As you can see, it will be quite similar to the above one: #+BEGIN_SRC emacs-lisp - (defun phundrak//eshell-banner--display-partition (part left-pad ramp-length) - (concat (s-pad-right left-pad "." - (with-face (phundrak/mounted-partitions-path part) - :weight 'bold)) - ": " - (phundrak//eshell-banner--progress-bar ramp-length - (phundrak/mounted-partitions-percent part)) - (format " %6s / %-5s (%s%%)" - (phundrak/mounted-partitions-used part) - (phundrak/mounted-partitions-size part) - (phundrak//eshell-banner--color-percentage (phundrak/mounted-partitions-percent part))))) +(defun phundrak//eshell-banner--display-partition (part left-pad ramp-length) + (concat (s-pad-right left-pad "." + (with-face (phundrak/mounted-partitions-path part) + :weight 'bold)) + ": " + (phundrak//eshell-banner--progress-bar ramp-length + (phundrak/mounted-partitions-percent part)) + (format " %6s / %-5s (%s%%)" + (phundrak/mounted-partitions-used part) + (phundrak/mounted-partitions-size part) + (phundrak//eshell-banner--color-percentage (phundrak/mounted-partitions-percent part))))) #+END_SRC And we can now build our banner! Here is our function that does exactly that: #+BEGIN_SRC emacs-lisp - (defun phundrak-eshell-banner () - (let* ((partitions (phundrak/get-mounted-partitions)) - (os (replace-regexp-in-string - ".*\"\\(.+\\)\"" - "\\1" - (car (-filter (lambda (line) - (s-contains? "PRETTY_NAME" line)) - (s-lines (phundrak-file-to-string "/etc/os-release")))))) - (memory (-map (lambda (line) - (s-split " " line t)) - (s-split "\n" - (shell-command-to-string "free -b | tail -2") - t))) - (ram (nth 0 memory)) - (swap (nth 1 memory)) - (ramp-length 41) - (left-pad (phundrak//eshell-banner--get-left-pad phundrak//eshell-banner--max-length-part partitions)) - (right-pad 8) - (left-column-width 27)) - (concat (format "%s\n" (s-repeat 79 "=")) - ;; OS and Kernel - (format "%s: %s%s: %s\n" - (s-pad-right left-pad "." "OS") - (s-pad-right left-column-width - " " - (with-face (s-trim os) - :weight 'bold)) - (s-pad-right right-pad "." "Kernel") - (with-face (concat "Linux " operating-system-release) - :weight 'bold)) - ;; Hostname and Uptime - (format "%s: %s%s: %s\n" - (s-pad-right left-pad "." "Hostname") - (s-pad-right left-column-width - " " - (with-face (system-name) :weight 'bold)) - (s-pad-right right-pad "." "Uptime") - (with-face (s-chop-prefix "up " - (s-trim (shell-command-to-string "uptime -p"))) - :weight 'bold)) - ;; RAM ramp - (phundrak//eshell-banner--display-memory "Ram" - (string-to-number (nth 2 ram)) - (string-to-number (nth 1 ram)) - left-pad - ramp-length) - ;; SWAP ramp - (phundrak//eshell-banner--display-memory "Swap" - (string-to-number (nth 2 swap)) - (string-to-number (nth 1 swap)) - left-pad - ramp-length) - ;; Partitions - (mapconcat (lambda (part) - (phundrak//eshell-banner--display-partition part left-pad ramp-length)) - partitions - "\n") - (format "\n%s\n" (s-repeat 79 "="))))) +(defun phundrak-eshell-banner () + (let* ((partitions (phundrak/get-mounted-partitions)) + (os (replace-regexp-in-string + ".*\"\\(.+\\)\"" + "\\1" + (car (-filter (lambda (line) + (s-contains? "PRETTY_NAME" line)) + (s-lines (phundrak-file-to-string "/etc/os-release")))))) + (memory (-map (lambda (line) + (s-split " " line t)) + (s-split "\n" + (shell-command-to-string "free -b | tail -2") + t))) + (ram (nth 0 memory)) + (swap (nth 1 memory)) + (ramp-length 41) + (left-pad (phundrak//eshell-banner--get-left-pad phundrak//eshell-banner--max-length-part partitions)) + (right-pad 8) + (left-column-width 27)) + (concat (format "%s\n" (s-repeat 79 "=")) + ;; OS and Kernel + (format "%s: %s%s: %s\n" + (s-pad-right left-pad "." "OS") + (s-pad-right left-column-width + " " + (with-face (s-trim os) + :weight 'bold)) + (s-pad-right right-pad "." "Kernel") + (with-face (concat "Linux " operating-system-release) + :weight 'bold)) + ;; Hostname and Uptime + (format "%s: %s%s: %s\n" + (s-pad-right left-pad "." "Hostname") + (s-pad-right left-column-width + " " + (with-face (system-name) :weight 'bold)) + (s-pad-right right-pad "." "Uptime") + (with-face (s-chop-prefix "up " + (s-trim (shell-command-to-string "uptime -p"))) + :weight 'bold)) + ;; RAM ramp + (phundrak//eshell-banner--display-memory "Ram" + (string-to-number (nth 2 ram)) + (string-to-number (nth 1 ram)) + left-pad + ramp-length) + ;; SWAP ramp + (phundrak//eshell-banner--display-memory "Swap" + (string-to-number (nth 2 swap)) + (string-to-number (nth 1 swap)) + left-pad + ramp-length) + ;; Partitions + (mapconcat (lambda (part) + (phundrak//eshell-banner--display-partition part left-pad ramp-length)) + partitions + "\n") + (format "\n%s\n" (s-repeat 79 "="))))) #+END_SRC We now only have to set the result of this function as our Eshell banner. Since @@ -2487,9 +2485,9 @@ a simple ~setq~ would only run ~phundrak-eshell-banner~ once when Emacs starts, we’ll actually make Emacs set the value of ~eshell-banner-message~ each time it is required by Eshell with a hook: #+BEGIN_SRC emacs-lisp - (add-hook 'eshell-banner-load-hook - (lambda () - (setq eshell-banner-message (phundrak-eshell-banner)))) +(add-hook 'eshell-banner-load-hook + (lambda () + (setq eshell-banner-message (phundrak-eshell-banner)))) #+END_SRC **** Eshell theme and prompt @@ -2504,73 +2502,72 @@ value of ~phundrak-prompt--abbreviate~, if it is ~t~ it is abbreviated; otherwise, it is kept in full. It can be toggled with a keyboard shortcut, see [[#User_Configuration-Shortcuts-Toggle-d53c27ef][Keybindings: Toggle]]. #+BEGIN_SRC emacs-lisp - (defun phundrak-eshell-prompt () - "Definition of my prompt for Eshell +(defun phundrak-eshell-prompt () + "Definition of my prompt for Eshell +It displays a powerline prompt, with first an abbreviated path to +the current directory. If `phundrak-prompt--abbreviate' is `t', +then all preceding directories will be abbreviated to one +character, except hidden directory which first character will be +preceded by a dot. Otherwise, the full name of the directories is +displayed. - It displays a powerline prompt, with first an abbreviated path to - the current directory. If `phundrak-prompt--abbreviate' is `t', - then all preceding directories will be abbreviated to one - character, except hidden directory which first character will be - preceded by a dot. Otherwise, the full name of the directories is - displayed. +Then, if the current directory is a git repository or one of its +subdirectories, it will display the current state of the +repository. See `phundrak-eshell-git-status' - Then, if the current directory is a git repository or one of its - subdirectories, it will display the current state of the - repository. See `phundrak-eshell-git-status' - - Finally, a lambda character is displayed, either in blue or in - red depending on if the last eshell command was a success or a - failure respectively." - (let* ((header-bg phundrak-nord0) - ($path (phundrak-abbr-path (eshell/pwd))) - ($git-path (phundrak-git-repo-root $path)) - ($abbr-path (phundrak-abbr-path $path phundrak-prompt--abbreviate)) - ($background phundrak-nord1) - ($foreground phundrak-nord14) - ($success phundrak-nord10) - ($error phundrak-nord11)) - (concat (with-face (concat " " - (phundrak-abbr-path (if $git-path - $git-path - $path) - phundrak-prompt--abbreviate) - " ") - :foreground $foreground - :background $background) - (when $git-path - (concat (phundrak-eshell-git-status $path $background) - (with-face (format "%s " - (let (($in-git-path (phundrak-abbr-path (f-relative $path $git-path) - phundrak-prompt--abbreviate))) - (if (string= "." $in-git-path) - "" - (concat " " $in-git-path)))) - :foreground $foreground - :background $background))) - (with-face "λ " - :foreground (if (zerop eshell-last-command-status) - $success - $error) - :background $background) - (with-face "" :foreground $background) - " "))) +Finally, a lambda character is displayed, either in blue or in +red depending on if the last eshell command was a success or a +failure respectively." + (let* ((header-bg phundrak-nord0) + ($path (phundrak-abbr-path (eshell/pwd))) + ($git-path (phundrak-git-repo-root $path)) + ($abbr-path (phundrak-abbr-path $path phundrak-prompt--abbreviate)) + ($background phundrak-nord1) + ($foreground phundrak-nord14) + ($success phundrak-nord10) + ($error phundrak-nord11)) + (concat (with-face (concat " " + (phundrak-abbr-path (if $git-path + $git-path + $path) + phundrak-prompt--abbreviate) + " ") + :foreground $foreground + :background $background) + (when $git-path + (concat (phundrak-eshell-git-status $path $background) + (with-face (format "%s " + (let (($in-git-path (phundrak-abbr-path (f-relative $path $git-path) + phundrak-prompt--abbreviate))) + (if (string= "." $in-git-path) + "" + (concat " " $in-git-path)))) + :foreground $foreground + :background $background))) + (with-face "λ " + :foreground (if (zerop eshell-last-command-status) + $success + $error) + :background $background) + (with-face "" :foreground $background) + " "))) #+END_SRC Now, let’s declare our prompt regexp and our prompt functions: #+BEGIN_SRC emacs-lisp - (setq eshell-prompt-regexp "^[^\n]*λ  " - eshell-prompt-function 'phundrak-eshell-prompt) +(setq eshell-prompt-regexp "^[^\n]*λ  " + eshell-prompt-function 'phundrak-eshell-prompt) #+END_SRC I also don't want the banner to be displayed, I know I entered the Elisp shell, no need to remind me. Maybe I’ll do something with it one day. #+BEGIN_SRC emacs-lisp - (setq eshell-banner-message "") +(setq eshell-banner-message "") #+END_SRC Finally, let’s enable some fish-like syntax highlighting: #+BEGIN_SRC emacs-lisp - (eshell-syntax-highlighting-global-mode +1) +(eshell-syntax-highlighting-global-mode +1) #+END_SRC ***** TODO Fix right column padding :noexport: @@ -2597,10 +2594,10 @@ is present or not (basically use the function ~battery~). With Eshell, some commands don’t work very well, especially commands that create a TUI. So, let’s declare them as visual commands or subcommands: #+BEGIN_SRC emacs-lisp - (setq eshell-visual-commands - '("fish" "zsh" "bash" "tmux" "htop" "top" "vim" "bat" "nano") - eshell-visual-subcommands - '("git" "log" "l" "diff" "show")) +(setq eshell-visual-commands + '("fish" "zsh" "bash" "tmux" "htop" "top" "vim" "bat" "nano") + eshell-visual-subcommands + '("git" "log" "l" "diff" "show")) #+END_SRC *** Org-mode @@ -2613,67 +2610,67 @@ discovered. It is awesome for writing documents, regardless of the format you need it to be exported to, for agenda management, and for literary programming, such as with this document. #+BEGIN_SRC emacs-lisp - (with-eval-after-load 'org - ;; configuration goes here - ) +(with-eval-after-load 'org + ;; configuration goes here + ) #+END_SRC #+BEGIN_SRC emacs-lisp :tangle ~/.emacs.spacemacs/private/user-config.el :exports none :noweb yes - (with-eval-after-load 'org - ;; agenda - <> - <> - ;; Babel - <> - <> - <> - <> - ;; Beautiful org - <> - <> - <> - <> - <> - <> - <> - <> - <> - ;; Capture - <> - <> - ;; Custom functions - ;;;; Better IDs - <> - <> - <> - <> - ;; File export - <> - ;;;; Latex - <> - <> - <> - <> - <> - ;;;; HTML - <> - <> - ;; Latex Formats - <> - ;; Projects - <> - ;; Variables - ;;;; Behavior - <> - <> - <> - <> - <> - <> - <> - ;;;; User information - <> - ) +(with-eval-after-load 'org + ;; agenda + <> + <> + ;; Babel + <> + <> + <> + <> + ;; Beautiful org + <> + <> + <> + <> + <> + <> + <> + <> + <> + ;; Capture + <> + <> + ;; Custom functions + ;;;; Better IDs + <> + <> + <> + <> + ;; File export + <> + ;;;; Latex + <> + <> + <> + <> + <> + ;;;; HTML + <> + <> + ;; Latex Formats + <> + ;; Projects + <> + ;; Variables + ;;;; Behavior + <> + <> + <> + <> + <> + <> + <> + ;;;; User information + <> + ) #+END_SRC **** Agenda @@ -2684,29 +2681,29 @@ One awesome feature of Org mode is the agenda. By default, my agendas are stored in =~/org/agenda=. #+NAME: org-agenda-files #+BEGIN_SRC emacs-lisp - (setq org-agenda-files (list "~/org/agenda" "~/org/notes.org")) +(setq org-agenda-files (list "~/org/agenda" "~/org/notes.org")) #+END_SRC I also have a custom command in Org agenda to mark some tasks as daily tasks with the =:DAILY:= tag,: #+NAME: org-agenda-custom-commands #+BEGIN_SRC emacs-lisp - (setq org-agenda-custom-commands - '(("h" "Daily habits" - ((agenda "")) - ((org-agenda-show-log t) - (org-agenda-ndays 7) - (org-agenda-log-mode-items '(state)) - (org-agenda-skip-function - '(org-agenda-skip-entry-if 'notregexp - ":DAILY:")))) - ("Y" "Yearly events" - ((agenda "")) - ((org-agenda-show-log t) - (org-agenda-ndays 365) - (org-agenda-log-mode-items '(state)) - (org-agenda-skip-entry-if 'notregexp - ":YEARLY:"))))) +(setq org-agenda-custom-commands + '(("h" "Daily habits" + ((agenda "")) + ((org-agenda-show-log t) + (org-agenda-ndays 7) + (org-agenda-log-mode-items '(state)) + (org-agenda-skip-function + '(org-agenda-skip-entry-if 'notregexp + ":DAILY:")))) + ("Y" "Yearly events" + ((agenda "")) + ((org-agenda-show-log t) + (org-agenda-ndays 365) + (org-agenda-log-mode-items '(state)) + (org-agenda-skip-entry-if 'notregexp + ":YEARLY:"))))) #+END_SRC **** Babel @@ -2736,11 +2733,11 @@ activated. Here are the languages I activated in my Org-mode configuration: #+header: :cache yes :results replace #+header: :var languages=org-babel-languages-table[,0] #+BEGIN_SRC emacs-lisp :exports none - (format "'(%s)" - (mapconcat (lambda ($language) - (format "(%s . t)" $language)) - languages - "\n ")) +(format "'(%s)" + (mapconcat (lambda ($language) + (format "(%s . t)" $language)) + languages + "\n ")) #+END_SRC #+RESULTS[71d98616bf4f1351ca93aea4972be0ba58057230]: org-babel-languages-gen @@ -2763,22 +2760,22 @@ activated. Here are the languages I activated in my Org-mode configuration: The corresponding code is as follows: #+NAME: org-babel-load-languages #+BEGIN_SRC emacs-lisp :noweb yes - (org-babel-do-load-languages - 'org-babel-load-languages - <>) +(org-babel-do-load-languages + 'org-babel-load-languages + <>) #+END_SRC Scheme requires a default implementation for geiser: #+NAME: org-babel-set-geiser #+BEGIN_SRC emacs-lisp - (setq geiser-default-implementation 'racket) +(setq geiser-default-implementation 'racket) #+END_SRC By the way, I wish to see source code behave the same way in the source blocks as in their own major mode. Let’s tell Emacs so: #+NAME: org-src-tab-acts-natively #+BEGIN_SRC emacs-lisp - (setq org-src-tab-acts-natively t) +(setq org-src-tab-acts-natively t) #+END_SRC Lastly, I know this can be a terrible idea, but I want Emacs to just evaluate @@ -2786,7 +2783,7 @@ Org code blocks without asking me. Of course, this could represent some big security issue if not careful enough, but I generaly just open my own org files. #+NAME: org-confirm-babel #+BEGIN_SRC emacs-lisp - (setq org-confirm-babel-evaluate nil) +(setq org-confirm-babel-evaluate nil) #+END_SRC **** Beautify Org-mode @@ -2808,10 +2805,10 @@ org-mode so we can get some proportional font. I’ll also remove ~auto-fill-mod which seems to stick to Orgmode like hell and I don’t know why. #+NAME: beautiful-org-hooks #+BEGIN_SRC emacs-lisp - (add-hook 'org-mode-hook 'visual-line-mode) - (remove-hook 'org-mode-hook 'auto-fill-mode) - (add-hook 'org-mode-hook 'variable-pitch-mode) - (auto-fill-mode -1) +(add-hook 'org-mode-hook 'visual-line-mode) +(remove-hook 'org-mode-hook 'auto-fill-mode) +(add-hook 'org-mode-hook 'variable-pitch-mode) +(auto-fill-mode -1) #+END_SRC You can then see the modified faces for org-mode [[#User-Configuration-Visual-configuration-Better-faces-Org-mode-07754177][here]]. @@ -2820,8 +2817,8 @@ By default, I would like my org-mode buffers to be indented and tables to be aligned. #+NAME: beautiful-org-options #+BEGIN_SRC emacs-lisp - (setq org-startup-indented t - org-startup-align-all-tables t) +(setq org-startup-indented t + org-startup-align-all-tables t) #+END_SRC ***** Fontifying parts of org-mode @@ -2854,101 +2851,101 @@ possible! And ~{{{results(...)}}}~ can also have the ~org-block~ face applied to match and make org-mode even more beautiful! Let’s do it: #+name: beautiful-org-fontify-inline #+BEGIN_SRC emacs-lisp - (defvar org-prettify-inline-results t - "Whether to use (ab)use prettify-symbols-mode on - {{{results(...)}}}.") +(defvar org-prettify-inline-results t + "Whether to use (ab)use prettify-symbols-mode on +{{{results(...)}}}.") - (defun org-fontify-inline-src-blocks (limit) - "Try to apply `org-fontify-inline-src-blocks-1'." - (condition-case nil - (org-fontify-inline-src-blocks-1 limit) - (error (message "Org mode fontification error in %S at %d" - (current-buffer) - (line-number-at-pos))))) +(defun org-fontify-inline-src-blocks (limit) + "Try to apply `org-fontify-inline-src-blocks-1'." + (condition-case nil + (org-fontify-inline-src-blocks-1 limit) + (error (message "Org mode fontification error in %S at %d" + (current-buffer) + (line-number-at-pos))))) - (defun org-fontify-inline-src-blocks-1 (limit) - "Fontify inline src_LANG blocks, from `point' up to `LIMIT'." - (let ((case-fold-search t)) - (when - ; stolen from `org-element-inline-src-block-parser' - (re-search-forward "\\_> info caddr (alist-get :file)))) - (unless file-name - (setq file-name (make-temp-file "babel-lsp-"))) - (setq buffer-file-name file-name) - (lsp-deferred))) - (put ',intern-pre 'function-documentation - (format "Enable lsp-mode in the buffer of org source block (%s)." - (upcase ,lang))) - (if (fboundp ',edit-pre) - (advice-add ',edit-pre :after ',intern-pre) - (progn - (defun ,edit-pre (info) - (,intern-pre info)) - (put ',edit-pre 'function-documentation - (format "Prepare local buffer environment for org source block (%s)." - (upcase ,lang)))))))) - (defvar org-babel-lsp-lang-list - '(<>)) - (dolist (lang org-babel-lsp-lang-list) - (eval `(lsp-org-babel-enable ,lang))) +(cl-defmacro lsp-org-babel-enable (lang) + "Support LANG in org source code block." + (setq centaur-lsp 'lsp-mode) + (cl-check-type lang stringp) + (let* ((edit-pre (intern (format "org-babel-edit-prep:%s" lang))) + (intern-pre (intern (format "lsp--%s" (symbol-name edit-pre))))) + `(progn + (defun ,intern-pre (info) + (let ((file-name (->> info caddr (alist-get :file)))) + (unless file-name + (setq file-name (make-temp-file "babel-lsp-"))) + (setq buffer-file-name file-name) + (lsp-deferred))) + (put ',intern-pre 'function-documentation + (format "Enable lsp-mode in the buffer of org source block (%s)." + (upcase ,lang))) + (if (fboundp ',edit-pre) + (advice-add ',edit-pre :after ',intern-pre) + (progn + (defun ,edit-pre (info) + (,intern-pre info)) + (put ',edit-pre 'function-documentation + (format "Prepare local buffer environment for org source block (%s)." + (upcase ,lang)))))))) +(defvar org-babel-lsp-lang-list + '(<>)) +(dolist (lang org-babel-lsp-lang-list) + (eval `(lsp-org-babel-enable ,lang))) #+END_SRC Here is one behavior that I really want to see modified: the ability to use ~M-RET~ without slicing the text the marker is on. #+NAME: org-M-RET-may-split-line #+BEGIN_SRC emacs-lisp - (setq org-M-RET-may-split-line nil) +(setq org-M-RET-may-split-line nil) #+END_SRC Since Org 9.3, Org no longer attempts to restore the window configuration in the @@ -3121,7 +3118,7 @@ for me, so I chose to set this variable to ~split-window-right~ in order to keep my windows organization and have a similar behavior to the old one. #+NAME: org-src-window-setup #+BEGIN_SRC emacs-lisp - (setq org-src-window-setup 'split-window-below) +(setq org-src-window-setup 'split-window-below) #+END_SRC However, it is not rare that I want to change that for an horizontal split, @@ -3130,27 +3127,27 @@ this function that allows me to switch between the (default) vertical split and the horizontal split. #+NAME: org-src-window-toggle #+BEGIN_SRC emacs-lisp - (defun phundrak/toggle-org-src-window-split () - "This function allows the user to toggle the behavior of - `org-edit-src-code'. If the variable `org-src-window-setup' has - the value `split-window-right', then it will be changed to - `split-window-below'. Otherwise, it will be set back to - `split-window-right'" - (interactive) - (if (equal org-src-window-setup 'split-window-right) - (setq org-src-window-setup 'split-window-below) - (setq org-src-window-setup 'split-window-right)) - (message "Org-src buffers will now split %s" - (if (equal org-src-window-setup 'split-window-right) - "vertically" - "horizontally"))) +(defun phundrak/toggle-org-src-window-split () + "This function allows the user to toggle the behavior of +`org-edit-src-code'. If the variable `org-src-window-setup' has +the value `split-window-right', then it will be changed to +`split-window-below'. Otherwise, it will be set back to +`split-window-right'" + (interactive) + (if (equal org-src-window-setup 'split-window-right) + (setq org-src-window-setup 'split-window-below) + (setq org-src-window-setup 'split-window-right)) + (message "Org-src buffers will now split %s" + (if (equal org-src-window-setup 'split-window-right) + "vertically" + "horizontally"))) #+END_SRC When creating a link to an Org flie, I want to create an ID only if the link is created interactively, and only if there is no custom ID already created. #+NAME: org-id-link-to-org #+BEGIN_SRC emacs-lisp - (setq org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id) +(setq org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id) #+END_SRC The tag ~:noexport:~ is fine and all, but it doesn’t allow for hidden org @@ -3158,8 +3155,8 @@ structures, that is headers that are visible in the org buffer but once the file is exported to another format the header disappears but its content stays. ~ox-extra~ has such a feature through ~ignore-headlines~. #+BEGIN_SRC emacs-lisp - (require 'ox-extra) - (ox-extras-activate '(ignore-headlines)) +(require 'ox-extra) +(ox-extras-activate '(ignore-headlines)) #+END_SRC This gives us access to the ~:ignore:~ tag which allows the behavior above mentioned. @@ -3174,14 +3171,14 @@ links, resources, reminders, and notes in neatly organized org files. Here they are described: #+NAME: org-capture-target-files #+BEGIN_SRC emacs-lisp - (defvar org-conlanging-file "~/org/conlanging.org") - (defvar org-default-notes-file "~/org/notes.org") - (defvar org-journal-file "~/org/journal.org") - (defvar org-linguistics-notes-file "~/org/linguistics-notes.org") - (defvar org-novel-notes-file "~/org/novel-notes.org") - (defvar org-private-agenda-file "~/org/agenda/private.org") - (defvar org-school-agenda-file "~/org/agenda/school.org") - (defvar org-wordbuilding-file "~/org/worldbuilding.org") +(defvar org-conlanging-file "~/org/conlanging.org") +(defvar org-default-notes-file "~/org/notes.org") +(defvar org-journal-file "~/org/journal.org") +(defvar org-linguistics-notes-file "~/org/linguistics-notes.org") +(defvar org-novel-notes-file "~/org/novel-notes.org") +(defvar org-private-agenda-file "~/org/agenda/private.org") +(defvar org-school-agenda-file "~/org/agenda/school.org") +(defvar org-wordbuilding-file "~/org/worldbuilding.org") #+END_SRC With Spacemacs, an Org capture can be invoked with the shortcut ~SPC a o c~. It @@ -3228,22 +3225,22 @@ is a new org node with a headline and some content. #+NAME: org-capture-shortcut-gen #+header: :exports none :cache yes :results replace #+BEGIN_SRC emacs-lisp :var table=org-capture-shortcuts-table - (format "'(%s)" - (mapconcat (lambda (entry) - (let* ((shortcut (nth 0 entry)) - (name (nth 1 entry)) - (title (nth 2 entry)) - (insertmode (nth 3 entry)) - (fileinsert (nth 4 entry)) - (sourceorg (nth 5 entry))) - (if (string= "" insertmode) - (format "(\"%s\" \"%s\")" shortcut name) - (concat (format "(\"%s\" \"%s\" entry\n" shortcut name) - (format " (%s %s%s)\n" insertmode fileinsert - (if (string= "file+datetree" insertmode) "" - (format " \"%s\"" (if (string= "" title) name title)))) - (format " (file \"~/org/capture/%s\"))" sourceorg)))) ) - table "\n ")) +(format "'(%s)" + (mapconcat (lambda (entry) + (let* ((shortcut (nth 0 entry)) + (name (nth 1 entry)) + (title (nth 2 entry)) + (insertmode (nth 3 entry)) + (fileinsert (nth 4 entry)) + (sourceorg (nth 5 entry))) + (if (string= "" insertmode) + (format "(\"%s\" \"%s\")" shortcut name) + (concat (format "(\"%s\" \"%s\" entry\n" shortcut name) + (format " (%s %s%s)\n" insertmode fileinsert + (if (string= "file+datetree" insertmode) "" + (format " \"%s\"" (if (string= "" title) name title)))) + (format " (file \"~/org/capture/%s\"))" sourceorg)))) ) + table "\n ")) #+END_SRC #+RESULTS[ec10a65e789d0f3d318de419a7c08e1f41dcb65a]: org-capture-shortcut-gen @@ -3325,9 +3322,9 @@ is a new org node with a headline and some content. Below you can find the equivalent code as described above. #+NAME: org-capture-templates #+BEGIN_SRC emacs-lisp :noweb yes - (setq - org-capture-templates - <>) +(setq + org-capture-templates + <>) #+END_SRC You may notice a capture entry for my journal, and this is due to the fact I do @@ -3358,42 +3355,42 @@ that won’t change over time. This code was taken from function’s job is to create these unique IDs #+NAME: org-better-id-new #+BEGIN_SRC emacs-lisp - (defun eos/org-id-new (&optional prefix) - "Create a new globally unique ID. +(defun eos/org-id-new (&optional prefix) + "Create a new globally unique ID. - An ID consists of two parts separated by a colon: - - a prefix - - a unique part that will be created according to - `org-id-method'. +An ID consists of two parts separated by a colon: +- a prefix +- a unique part that will be created according to + `org-id-method'. - PREFIX can specify the prefix, the default is given by the - variable `org-id-prefix'. However, if PREFIX is the symbol - `none', don't use any prefix even if `org-id-prefix' specifies - one. +PREFIX can specify the prefix, the default is given by the +variable `org-id-prefix'. However, if PREFIX is the symbol +`none', don't use any prefix even if `org-id-prefix' specifies +one. - So a typical ID could look like \"Org-4nd91V40HI\"." - (let* ((prefix (if (eq prefix 'none) - "" - (concat (or prefix org-id-prefix) - "-"))) unique) - (when (equal prefix "-") - (setq prefix "")) - (cond - ((memq org-id-method - '(uuidgen uuid)) - (setq unique (org-trim (shell-command-to-string org-id-uuid-program))) - (unless (org-uuidgen-p unique) - (setq unique (org-id-uuid)))) - ((eq org-id-method 'org) - (let* ((etime (org-reverse-string (org-id-time-to-b36))) - (postfix (when org-id-include-domain - (progn - (require 'message) - (concat "@" - (message-make-fqdn)))))) - (setq unique (concat etime postfix)))) - (t (error "Invalid `org-id-method'"))) - (concat prefix (car (split-string unique "-"))))) +So a typical ID could look like \"Org-4nd91V40HI\"." + (let* ((prefix (if (eq prefix 'none) + "" + (concat (or prefix org-id-prefix) + "-"))) unique) + (when (equal prefix "-") + (setq prefix "")) + (cond + ((memq org-id-method + '(uuidgen uuid)) + (setq unique (org-trim (shell-command-to-string org-id-uuid-program))) + (unless (org-uuidgen-p unique) + (setq unique (org-id-uuid)))) + ((eq org-id-method 'org) + (let* ((etime (org-reverse-string (org-id-time-to-b36))) + (postfix (when org-id-include-domain + (progn + (require 'message) + (concat "@" + (message-make-fqdn)))))) + (setq unique (concat etime postfix)))) + (t (error "Invalid `org-id-method'"))) + (concat prefix (car (split-string unique "-"))))) #+END_SRC Now, let’s see the function that will be used to get the custom id of a heading @@ -3401,36 +3398,35 @@ at point. If the function does not detect any custom ID, then one should be created and inserted. #+NAME: org-better-id-get #+BEGIN_SRC emacs-lisp - (defun eos/org-custom-id-get (&optional pom create prefix) - "Get the CUSTOM_ID property of the entry at point-or-marker POM. - - If POM is nil, refer to the entry at point. If the entry does not - have an CUSTOM_ID, the function returns nil. However, when CREATE - is non nil, create a CUSTOM_ID if none is present already. PREFIX - will be passed through to `eos/org-id-new'. In any case, the - CUSTOM_ID of the entry is returned." - (interactive) - (org-with-point-at pom - (let* ((orgpath (mapconcat #'identity (org-get-outline-path) "-")) - (heading (replace-regexp-in-string - "[_-]+$" "" - (replace-regexp-in-string - "[-_]+" "-" - (replace-regexp-in-string - "[^a-zA-Z0-9-_]" "-" - (if (string= orgpath "") - (org-get-heading t t t t) - (concat orgpath "_" (org-get-heading t t t t))))))) - (id (org-entry-get nil "CUSTOM_ID"))) - (cond - ((and id - (stringp id) - (string-match "\\S-" id)) id) - (create (setq id (eos/org-id-new (concat prefix heading))) - (org-entry-put pom "CUSTOM_ID" id) - (org-id-add-location id - (buffer-file-name (buffer-base-buffer))) - id))))) +(defun eos/org-custom-id-get (&optional pom create prefix) + "Get the CUSTOM_ID property of the entry at point-or-marker POM. +If POM is nil, refer to the entry at point. If the entry does not +have an CUSTOM_ID, the function returns nil. However, when CREATE +is non nil, create a CUSTOM_ID if none is present already. PREFIX +will be passed through to `eos/org-id-new'. In any case, the +CUSTOM_ID of the entry is returned." + (interactive) + (org-with-point-at pom + (let* ((orgpath (mapconcat #'identity (org-get-outline-path) "-")) + (heading (replace-regexp-in-string + "[_-]+$" "" + (replace-regexp-in-string + "[-_]+" "-" + (replace-regexp-in-string + "[^a-zA-Z0-9-_]" "-" + (if (string= orgpath "") + (org-get-heading t t t t) + (concat orgpath "_" (org-get-heading t t t t))))))) + (id (org-entry-get nil "CUSTOM_ID"))) + (cond + ((and id + (stringp id) + (string-match "\\S-" id)) id) + (create (setq id (eos/org-id-new (concat prefix heading))) + (org-entry-put pom "CUSTOM_ID" id) + (org-id-add-location id + (buffer-file-name (buffer-base-buffer))) + id))))) #+END_SRC Finally, this is the function that gets called on file saves. If the function @@ -3438,31 +3434,31 @@ detects ~auto-id:t~ among the org options in the ~#+OPTIONS:~ header, then the above function is called. #+NAME: org-better-id-add-ids #+BEGIN_SRC emacs-lisp - (defun eos/org-add-ids-to-headlines-in-file () - "Add CUSTOM_ID properties to all headlines in the current file - which do not already have one. +(defun eos/org-add-ids-to-headlines-in-file () + "Add CUSTOM_ID properties to all headlines in the current file +which do not already have one. - Only adds ids if the `auto-id' option is set to `t' in the file - somewhere. ie, #+OPTIONS: auto-id:t" - (interactive) - (save-excursion - (widen) - (goto-char (point-min)) - (when (re-search-forward "^#\\+OPTIONS:.*auto-id:t" (point-max) t) - (org-map-entries (lambda () (eos/org-custom-id-get (point) 'create)))))) +Only adds ids if the `auto-id' option is set to `t' in the file +somewhere. ie, #+OPTIONS: auto-id:t" + (interactive) + (save-excursion + (widen) + (goto-char (point-min)) + (when (re-search-forward "^#\\+OPTIONS:.*auto-id:t" (point-max) t) + (org-map-entries (lambda () (eos/org-custom-id-get (point) 'create)))))) #+END_SRC Let’s add a hook to the above function so it is called automatically on save, and only in read-write functions. #+NAME: org-better-id-hooks #+BEGIN_SRC emacs-lisp - (add-hook 'org-mode-hook - (lambda () - (add-hook 'before-save-hook - (lambda () - (when (and (eq major-mode 'org-mode) - (eq buffer-read-only nil)) - (eos/org-add-ids-to-headlines-in-file)))))) +(add-hook 'org-mode-hook + (lambda () + (add-hook 'before-save-hook + (lambda () + (when (and (eq major-mode 'org-mode) + (eq buffer-read-only nil)) + (eos/org-add-ids-to-headlines-in-file)))))) #+END_SRC **** File export @@ -3476,7 +3472,7 @@ not a markup one, especially when describing phonetics evolution. So, let’s disable it: #+NAME: org-use-sub-superscripts #+BEGIN_SRC emacs-lisp - (setq org-use-sub-superscripts (quote {})) +(setq org-use-sub-superscripts (quote {})) #+END_SRC ***** LaTeX @@ -3487,14 +3483,14 @@ When it comes to exports, I want the LaTeX and PDF exports to be done with XeLaTeX only. This implies the modification of the following variable: #+NAME: org-latex-compiler #+BEGIN_SRC emacs-lisp - (setq org-latex-compiler "xelatex") +(setq org-latex-compiler "xelatex") #+END_SRC I also want to get by default ~minted~ for LaTeX listings so I can have syntax highlights: #+NAME: org-latex-listings #+BEGIN_SRC emacs-lisp - (setq org-latex-listings 'minted) +(setq org-latex-listings 'minted) #+END_SRC The default packages break my LaTeX exports: for some reasons, images are not @@ -3504,24 +3500,24 @@ excluding the one that broke my exports. I also added two default packages, Chinese and Korean) support. #+NAME: org-latex-default-packages #+BEGIN_SRC emacs-lisp - (setq org-latex-default-packages-alist '(("" "graphicx" t) - ("T1" "fontspec" t ("pdflatex")) - ("" "longtable" nil) - ("" "wrapfig" nil) - ("" "rotating" nil) - ("normalem" "ulem" t) - ("" "amsmath" t) - ("" "textcomp" t) - ("" "amssymb" t) - ("" "capt-of" nil) - ("" "minted" nil) - ("" "hyperref" nil))) +(setq org-latex-default-packages-alist '(("" "graphicx" t) + ("T1" "fontspec" t ("pdflatex")) + ("" "longtable" nil) + ("" "wrapfig" nil) + ("" "rotating" nil) + ("normalem" "ulem" t) + ("" "amsmath" t) + ("" "textcomp" t) + ("" "amssymb" t) + ("" "capt-of" nil) + ("" "minted" nil) + ("" "hyperref" nil))) #+END_SRC By the way, reference links in LaTeX should be written in this format: #+NAME: org-export-latex-hyperref-format #+BEGIN_SRC emacs-lisp - (setq org-export-latex-hyperref-format "\\ref{%s}") +(setq org-export-latex-hyperref-format "\\ref{%s}") #+END_SRC When it comes to the export itself, the latex file needs to be processed several @@ -3529,11 +3525,11 @@ times through XeLaTeX in order to get some references right. Don’t forget to also run bibtex! #+NAME: org-latex-pdf-process #+BEGIN_SRC emacs-lisp - (setq org-latex-pdf-process - '("xelatex -8bit -shell-escape -interaction nonstopmode -output-directory %o %f" - "bibtex %b" - "xelatex -8bit -shell-escape -interaction nonstopmode -output-directory %o %f" - "xelatex -8bit -shell-escape -interaction nonstopmode -output-directory %o %f")) +(setq org-latex-pdf-process + '("xelatex -8bit -shell-escape -interaction nonstopmode -output-directory %o %f" + "bibtex %b" + "xelatex -8bit -shell-escape -interaction nonstopmode -output-directory %o %f" + "xelatex -8bit -shell-escape -interaction nonstopmode -output-directory %o %f")) #+END_SRC ***** HTML @@ -3543,73 +3539,73 @@ also run bibtex! For Reveal.JS exports, I need to set where to find the framework by default: #+NAME: org-re-reveal-root #+BEGIN_SRC emacs-lisp - (setq org-re-reveal-root "https://cdn.jsdelivr.net/npm/reveal.js") +(setq org-re-reveal-root "https://cdn.jsdelivr.net/npm/reveal.js") #+END_SRC On HTML exports, Org-mode tries to include a validation link for the exported HTML. Let’s disable that since I never use it. #+NAME: org-html-validation #+BEGIN_SRC emacs-lisp - (setq org-html-validation-link nil) +(setq org-html-validation-link nil) #+END_SRC However, something I very often use are metadata information in my HTML files. I just want to automate that. Fortunately, [[https://tecosaur.github.io/emacs-config/config.html#extra-header-content,code--3][Tecosaur comes to the rescue]]! First, here is our function that will generate all the meta tags in our HTML: #+BEGIN_SRC emacs-lisp - (defun org-html-meta-tags-fancy (info) - "Use the INFO plist to construct the meta tags, as described in - `org-html-meta-tags'." - (message "%s" info) - (let ((title (org-html-plain-text - (org-element-interpret-data (plist-get info :title)) info)) - (author (and (plist-get info :with-author) - (let ((auth (plist-get info :author))) - ;; Return raw Org syntax. - (and auth (org-html-plain-text - (org-element-interpret-data auth) info)))))) - (list - (when (org-string-nw-p author) - (list "name" "author" author)) - (when (org-string-nw-p (plist-get info :description)) - (list "name" "description" - (plist-get info :description))) - '("name" "generator" "org mode (Emacs)") - '("name" "theme-color" "#3b4252") - '("property" "og:type" "article") - (list "property" "og:title" title) - (let ((subtitle (org-export-data (plist-get info :subtitle) info))) - (when (org-string-nw-p subtitle) - (list "property" "og:description" subtitle))) - (let ((meta-image (org-export-data (plist-get info :metaimage) info))) - (when (org-string-nw-p meta-image) - (list "property" "og:image" meta-image))) - (let ((meta-image-type (org-export-data (plist-get info :metaimagetype) info))) - (when (org-string-nw-p meta-image-type) - (list "property" "og:image:type" meta-image-type))) - (let ((meta-image-width (org-export-data (plist-get info :metaimagewidth) info))) - (when (org-string-nw-p meta-image-width) - (list "property" "og:image:width" meta-image-width))) - (let ((meta-image-height (org-export-data (plist-get info :metaimageheight) info))) - (when (org-string-nw-p meta-image-height) - (list "property" "og:image:height" meta-image-height))) - (let ((meta-image-alt (org-export-data (plist-get info :metaimagealt) info))) - (when (org-string-nw-p meta-image-alt) - (list "property" "og:image:alt" meta-image-alt))) - (when (org-string-nw-p author) - (list "property" "og:article:author:first_name" (car (s-split-up-to " " author 2)))) - (when (and (org-string-nw-p author) (s-contains-p " " author)) - (list "property" "og:article:author:last_name" (cadr (s-split-up-to " " author 2)))) - (list "property" "og:article:published_time" (format-time-string "%FT%T%z"))))) +(defun org-html-meta-tags-fancy (info) + "Use the INFO plist to construct the meta tags, as described in +`org-html-meta-tags'." + (message "%s" info) + (let ((title (org-html-plain-text + (org-element-interpret-data (plist-get info :title)) info)) + (author (and (plist-get info :with-author) + (let ((auth (plist-get info :author))) + ;; Return raw Org syntax. + (and auth (org-html-plain-text + (org-element-interpret-data auth) info)))))) + (list + (when (org-string-nw-p author) + (list "name" "author" author)) + (when (org-string-nw-p (plist-get info :description)) + (list "name" "description" + (plist-get info :description))) + '("name" "generator" "org mode (Emacs)") + '("name" "theme-color" "#3b4252") + '("property" "og:type" "article") + (list "property" "og:title" title) + (let ((subtitle (org-export-data (plist-get info :subtitle) info))) + (when (org-string-nw-p subtitle) + (list "property" "og:description" subtitle))) + (let ((meta-image (org-export-data (plist-get info :metaimage) info))) + (when (org-string-nw-p meta-image) + (list "property" "og:image" meta-image))) + (let ((meta-image-type (org-export-data (plist-get info :metaimagetype) info))) + (when (org-string-nw-p meta-image-type) + (list "property" "og:image:type" meta-image-type))) + (let ((meta-image-width (org-export-data (plist-get info :metaimagewidth) info))) + (when (org-string-nw-p meta-image-width) + (list "property" "og:image:width" meta-image-width))) + (let ((meta-image-height (org-export-data (plist-get info :metaimageheight) info))) + (when (org-string-nw-p meta-image-height) + (list "property" "og:image:height" meta-image-height))) + (let ((meta-image-alt (org-export-data (plist-get info :metaimagealt) info))) + (when (org-string-nw-p meta-image-alt) + (list "property" "og:image:alt" meta-image-alt))) + (when (org-string-nw-p author) + (list "property" "og:article:author:first_name" (car (s-split-up-to " " author 2)))) + (when (and (org-string-nw-p author) (s-contains-p " " author)) + (list "property" "og:article:author:last_name" (cadr (s-split-up-to " " author 2)))) + (list "property" "og:article:published_time" (format-time-string "%FT%T%z"))))) #+END_SRC This will use some special keywords in our org buffer and insert their content in Now let’s bind it to when we export our org buffer to HTML: #+BEGIN_SRC emacs-lisp - (unless (functionp #'org-html-meta-tags-default) - (defalias 'org-html-meta-tags-default #'ignore)) - (setq org-html-meta-tags #'org-html-meta-tags-fancy) +(unless (functionp #'org-html-meta-tags-default) + (defalias 'org-html-meta-tags-default #'ignore)) +(setq org-html-meta-tags #'org-html-meta-tags-fancy) #+END_SRC **** LaTeX formats @@ -3623,38 +3619,38 @@ exports. Below is the declaration of the ~conlang~ LaTeX class: #+NAME: org-latex-class-conlang #+BEGIN_SRC emacs-lisp - '("conlang" - "\\documentclass{book}" - ("\\chapter{%s}" . "\\chapter*{%s}") - ("\\section{%s}" . "\\section*{%s}") - ("\\subsection{%s}" . "\\subsection*{%s}") - ("\\subsubsection{%s}" . "\\subsubsection*{%s}")) +'("conlang" + "\\documentclass{book}" + ("\\chapter{%s}" . "\\chapter*{%s}") + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}")) #+END_SRC And here is the declaration of the ~beamer~ class: #+NAME: org-latex-class-beamer #+BEGIN_SRC emacs-lisp - `("beamer" - ,(concat "\\documentclass[presentation]{beamer}\n" - "[DEFAULT-PACKAGES]" - "[PACKAGES]" - "[EXTRA]\n") - ("\\section{%s}" . "\\section*{%s}") - ("\\subsection{%s}" . "\\subsection*{%s}") - ("\\subsubsection{%s}" . "\\subsubsection*{%s}")) +`("beamer" + ,(concat "\\documentclass[presentation]{beamer}\n" + "[DEFAULT-PACKAGES]" + "[PACKAGES]" + "[EXTRA]\n") + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}")) #+END_SRC Both these classes have to be added to ~org-latex-classes~ like so: #+NAME: org-latex-classes #+BEGIN_SRC emacs-lisp :noweb yes - (eval-after-load "ox-latex" - '(progn - (add-to-list 'org-latex-classes - <> - ) - (add-to-list 'org-latex-classes - <> - ))) +(eval-after-load "ox-latex" + '(progn + (add-to-list 'org-latex-classes + <> + ) + (add-to-list 'org-latex-classes + <> + ))) #+END_SRC **** Projects @@ -3666,17 +3662,17 @@ easily publish a bunch of org files to a remote location. Here is the current declaration of my projects, which will be detailed later: #+NAME: org-publish-projects #+BEGIN_SRC emacs-lisp :noweb yes - <> - <> - (setq org-publish-project-alist - `( - <> - <> - <> - <> - <> - <> - <>)) +<> +<> +(setq org-publish-project-alist + `( + <> + <> + <> + <> + <> + <> + <>)) #+END_SRC ***** Configuration website @@ -3694,18 +3690,18 @@ manually, but now I can change all three values at the same time without a hasle. #+NAME: org-proj-config-setup #+BEGIN_SRC emacs-lisp - (defvar phundrak//projects-config-target - "/rsync:Tilo:~/www/phundrak.com/config" - "Points to where exported files for config.phundrak.com should be put") - (defvar phundrak//projects-config-source - "~/org/config/" - "Points to where the sources for config.phundrak.com are") - (defvar phundrak//projects-config-language - "en" - "Language of config.phundrak.com") - (defvar phundrak//projects-config-recursive - t - "Defines whether subdirectories should be parsed for config.phundrak.com") +(defvar phundrak//projects-config-target + "/rsync:Tilo:~/www/phundrak.com/config" + "Points to where exported files for config.phundrak.com should be put") +(defvar phundrak//projects-config-source + "~/org/config/" + "Points to where the sources for config.phundrak.com are") +(defvar phundrak//projects-config-language + "en" + "Language of config.phundrak.com") +(defvar phundrak//projects-config-recursive + t + "Defines whether subdirectories should be parsed for config.phundrak.com") #+END_SRC Now, here is my configuration. In this snippet, my org files located in my @@ -3715,37 +3711,37 @@ automatically generated, which comes in handy with the online sitemap that is available through the navigation bar. #+NAME: org-proj-config-html #+BEGIN_SRC emacs-lisp - ("config-website-org" - :base-directory ,phundrak//projects-config-source - :base-extension "org" - :publishing-directory ,phundrak//projects-config-target - :recursive ,phundrak//projects-config-recursive - :language ,phundrak//projects-config-language - :publishing-function org-html-publish-to-html - :headline-levels 5 - :auto-sitemap t - :auto-preamble t) +("config-website-org" + :base-directory ,phundrak//projects-config-source + :base-extension "org" + :publishing-directory ,phundrak//projects-config-target + :recursive ,phundrak//projects-config-recursive + :language ,phundrak//projects-config-language + :publishing-function org-html-publish-to-html + :headline-levels 5 + :auto-sitemap t + :auto-preamble t) #+END_SRC We also have the component for all the static files needed to run the website (mostly images tbh). #+NAME: org-proj-config-static #+BEGIN_SRC emacs-lisp - ("config-website-static" - :base-directory ,phundrak//projects-config-source - :base-extension "png\\|jpg\\|gif\\|webp\\|svg\\|jpeg\\|ttf\\|woff\\|txt\\|epub\\|md" - :publishing-directory ,phundrak//projects-config-target - :recursive ,phundrak//projects-config-recursive - :language ,phundrak//projects-config-language - :publishing-function org-publish-attachment) +("config-website-static" + :base-directory ,phundrak//projects-config-source + :base-extension "png\\|jpg\\|gif\\|webp\\|svg\\|jpeg\\|ttf\\|woff\\|txt\\|epub\\|md" + :publishing-directory ,phundrak//projects-config-target + :recursive ,phundrak//projects-config-recursive + :language ,phundrak//projects-config-language + :publishing-function org-publish-attachment) #+END_SRC The project is then defined like so: #+NAME: org-proj-config #+BEGIN_SRC emacs-lisp - ("config-website" - :components ("config-website-org" - "config-website-static")) +("config-website" + :components ("config-website-org" + "config-website-static")) #+END_SRC ***** Linguistics website @@ -3756,71 +3752,71 @@ My linguistics website is made out of three projects. As for the previous project, let’s declare the common values for these. #+NAME: org-proj-lang-setup #+BEGIN_SRC emacs-lisp - (defvar phundrak//projects-conlanging-target - "/rsync:Tilo:~/www/phundrak.com/langue/" - "Points to where exported files for langue.phundrak.com should be put") - (defvar phundrak//projects-conlanging-source - "~/Documents/conlanging/content/" - "Points to where the sources for langue.phundrak.com are") - (defvar phundrak//projects-conlanging-language - "fr" - "Language of langue.phundrak.com") - (defvar phundrak//projects-conlanging-recursive - t - "Defines whether subdirectories should be parsed for langue.phundrak.com") +(defvar phundrak//projects-conlanging-target + "/rsync:Tilo:~/www/phundrak.com/langue/" + "Points to where exported files for langue.phundrak.com should be put") +(defvar phundrak//projects-conlanging-source + "~/Documents/conlanging/content/" + "Points to where the sources for langue.phundrak.com are") +(defvar phundrak//projects-conlanging-language + "fr" + "Language of langue.phundrak.com") +(defvar phundrak//projects-conlanging-recursive + t + "Defines whether subdirectories should be parsed for langue.phundrak.com") #+END_SRC The first component is the one generating the HTML files from the org files. #+NAME: org-proj-lang-html #+BEGIN_SRC emacs-lisp - ("langue-phundrak-com-org" - :base-directory ,phundrak//projects-conlanging-source - :base-extension "org" - :exclude "\\./\\(CONTRIB\\|README\\|head\\|temp\\|svg-ink\\).*" - :publishing-directory ,phundrak//projects-conlanging-target - :recursive ,phundrak//projects-conlanging-recursive - :language ,phundrak//projects-conlanging-language - :publishing-function org-html-publish-to-html - :headline-levels 5 - :auto-sitemap t - :auto-preamble t) +("langue-phundrak-com-org" + :base-directory ,phundrak//projects-conlanging-source + :base-extension "org" + :exclude "\\./\\(CONTRIB\\|README\\|head\\|temp\\|svg-ink\\).*" + :publishing-directory ,phundrak//projects-conlanging-target + :recursive ,phundrak//projects-conlanging-recursive + :language ,phundrak//projects-conlanging-language + :publishing-function org-html-publish-to-html + :headline-levels 5 + :auto-sitemap t + :auto-preamble t) #+END_SRC We also have the component for the LaTeX and PDF part of the website: #+NAME: org-proj-lang-pdf #+BEGIN_SRC emacs-lisp - ("langue-phundrak-com-pdf" - :base-directory ,phundrak//projects-conlanging-source - :base-extension "org" - :exclude "\\./\\(CONTRIB\\|README\\|index\\|head\\|temp\\|svg-ink\\).*" - :publishing-directory ,phundrak//projects-conlanging-target - :recursive ,phundrak//projects-conlanging-recursive - :language ,phundrak//projects-conlanging-language - :publishing-function org-latex-publish-to-pdf - :headline-levels 5 - :auto-preamble t) +("langue-phundrak-com-pdf" + :base-directory ,phundrak//projects-conlanging-source + :base-extension "org" + :exclude "\\./\\(CONTRIB\\|README\\|index\\|head\\|temp\\|svg-ink\\).*" + :publishing-directory ,phundrak//projects-conlanging-target + :recursive ,phundrak//projects-conlanging-recursive + :language ,phundrak//projects-conlanging-language + :publishing-function org-latex-publish-to-pdf + :headline-levels 5 + :auto-preamble t) #+END_SRC And lastly, we have the component for all the static files needed to run the website: #+NAME: org-proj-lang-static #+BEGIN_SRC emacs-lisp - ("langue-phundrak-com-static" - :base-directory ,phundrak//projects-conlanging-source - :base-extension "png\\|jpg\\|gif\\|webp\\|svg\\|jpeg\\|ttf\\|woff\\|txt\\|epub" - :publishing-directory ,phundrak//projects-conlanging-target - :recursive ,phundrak//projects-conlanging-recursive - :language ,phundrak//projects-conlanging-language - :publishing-function org-publish-attachment) +("langue-phundrak-com-static" + :base-directory ,phundrak//projects-conlanging-source + :base-extension "png\\|jpg\\|gif\\|webp\\|svg\\|jpeg\\|ttf\\|woff\\|txt\\|epub" + :publishing-directory ,phundrak//projects-conlanging-target + :recursive ,phundrak//projects-conlanging-recursive + :language ,phundrak//projects-conlanging-language + :publishing-function org-publish-attachment) #+END_SRC The project is then defined like so: #+NAME: org-proj-lang #+BEGIN_SRC emacs-lisp - ("langue-phundrak-com" - :components ("langue-phundrak-com-org" - "langue-phundrak-com-static" - "langue-phundrak-com-pdf")) +("langue-phundrak-com" + :components ("langue-phundrak-com-org" + "langue-phundrak-com-static" + "langue-phundrak-com-pdf")) #+END_SRC **** User information @@ -3831,10 +3827,10 @@ Some variables about myself need to be set so Org-mode knows what information to include in exported files. #+NAME: org-user-information #+BEGIN_SRC emacs-lisp - (setq user-full-name "Lucien Cartier-Tilet" - user-real-login-name "Lucien Cartier-Tilet" - user-login-name "phundrak" - user-mail-address "lucien@phundrak.com") +(setq user-full-name "Lucien Cartier-Tilet" + user-real-login-name "Lucien Cartier-Tilet" + user-login-name "phundrak" + user-mail-address "lucien@phundrak.com") #+END_SRC *** Recentf @@ -3858,16 +3854,16 @@ ignore these paths: #+name: recentf-ignored-paths-gen #+header: :var paths=recentf-ignored-paths #+BEGIN_SRC emacs-lisp :tangle no :exports none - (mapconcat (lambda (path) - (format "(add-to-list 'recentf-exclude\n (expand-file-name \"%s\"))" - (replace-regexp-in-string "=" "" (car path)))) - paths - "\n") +(mapconcat (lambda (path) + (format "(add-to-list 'recentf-exclude\n (expand-file-name \"%s\"))" + (replace-regexp-in-string "=" "" (car path)))) + paths + "\n") #+END_SRC #+BEGIN_SRC emacs-lisp :noweb yes - (with-eval-after-load 'recentf - <>) +(with-eval-after-load 'recentf + <>) #+END_SRC ** Keybindings @@ -3879,7 +3875,7 @@ Spacemacs keybindings, defined in a way they can be used seamlessly with Evil. They almost all begin with ~o~, which is a prefix reserved for user-defined keybindings so they won’t conflict with any package. Let’s declare it like so. #+BEGIN_SRC emacs-lisp - (spacemacs/declare-prefix "o" "custom") +(spacemacs/declare-prefix "o" "custom") #+END_SRC Now, all keybindings that will be defined can be invoked in Normal-mode with the @@ -3892,21 +3888,21 @@ bound to ~SPC ²~, which is not a key that is available on the bépo layout (instead, we use the dead key ~^~ followed by ~2~, or any digits). So instead, let’s use the key that is physically in the same place: ~$~. #+BEGIN_SRC emacs-lisp - (spacemacs/declare-prefix "$" "select window by number") - (spacemacs/set-leader-keys "$" 'winum-select-window-by-number) +(spacemacs/declare-prefix "$" "select window by number") +(spacemacs/set-leader-keys "$" 'winum-select-window-by-number) #+END_SRC The following, I use it rarely, it can launch an external command from Emacs to launch, for instance, my web browser or any other software not related to Emacs. It offers a similar interface to [[https://wiki.archlinux.org/index.php/Dmenu][dmenu]] through helm. #+BEGIN_SRC emacs-lisp - (spacemacs/declare-prefix "or" "external command") - (spacemacs/set-leader-keys "or" 'helm-run-external-command) +(spacemacs/declare-prefix "or" "external command") +(spacemacs/set-leader-keys "or" 'helm-run-external-command) #+END_SRC However this one I use often, generally in org or text buffers. #+BEGIN_SRC emacs-lisp - (spacemacs/set-leader-keys "os" 'sort-lines) +(spacemacs/set-leader-keys "os" 'sort-lines) #+END_SRC *** Applications @@ -3915,7 +3911,7 @@ However this one I use often, generally in org or text buffers. :END: As this is a new category, let’s declare its prefix: #+BEGIN_SRC emacs-lisp - (spacemacs/declare-prefix "oa" "applications") +(spacemacs/declare-prefix "oa" "applications") #+END_SRC Now, let’s also declare the keybindings in this category. ~oac~ will invoke @@ -3925,13 +3921,13 @@ will invoke Eshell directly, without any popup window as with ~SPC '~ while ~oan~ will open a new eshell buffer if another one already exists. ~ov~ will also open a vterm terminal. #+BEGIN_SRC emacs-lisp - (spacemacs/set-leader-keys - "o'" 'eshell-new - "ov" 'vterm - "oac" 'calc - "oaC" 'calendar - "oae" 'eww - "oaw" 'wttrin) +(spacemacs/set-leader-keys + "o'" 'eshell-new + "ov" 'vterm + "oac" 'calc + "oaC" 'calendar + "oae" 'eww + "oaw" 'wttrin) #+END_SRC **** Image mode @@ -3942,13 +3938,13 @@ Viewing images in Emacs is nice, but I want to be able to do more than just view them, such as opening them in GIMP. I’ll also declare a couple of keybindings that make sense to me. #+BEGIN_SRC emacs-lisp - (spacemacs/declare-prefix-for-mode 'image-mode "G" "Open in GIMP") - (spacemacs/declare-prefix-for-mode 'image-mode "o" "Open in external viewer") - (spacemacs/declare-prefix-for-mode 'image-mode "r" "Rotate clockwise") - (spacemacs/set-leader-keys-for-major-mode 'image-mode - "G" (lambda () (interactive) (start-process "" nil "gimp" (buffer-name))) - "o" (lambda () (interactive) (start-process "" nil "xdg-open" (buffer-name))) - "r" 'image-rotate) +(spacemacs/declare-prefix-for-mode 'image-mode "G" "Open in GIMP") +(spacemacs/declare-prefix-for-mode 'image-mode "o" "Open in external viewer") +(spacemacs/declare-prefix-for-mode 'image-mode "r" "Rotate clockwise") +(spacemacs/set-leader-keys-for-major-mode 'image-mode + "G" (lambda () (interactive) (start-process "" nil "gimp" (buffer-name))) + "o" (lambda () (interactive) (start-process "" nil "xdg-open" (buffer-name))) + "r" 'image-rotate) #+END_SRC **** Org tree slide @@ -3960,8 +3956,8 @@ with orgmode. Since I want the keys to be directly accessible without any prefix from Spacemacs, I’ll have to declare them the vanilla way. First we have keybindings that will launch the presentation: #+BEGIN_SRC emacs-lisp - (define-key org-mode-map (kbd "") 'org-tree-slide-mode) - (define-key org-mode-map (kbd "s-") 'org-tree-slide-skip-done-toggle) +(define-key org-mode-map (kbd "") 'org-tree-slide-mode) +(define-key org-mode-map (kbd "s-") 'org-tree-slide-skip-done-toggle) #+END_SRC Next, we have some additional keybindings that will only be active when in @@ -3972,18 +3968,18 @@ way the content is displayed. We also set ~org-tree-slide-skip-outline-level~ to set the maximum depth we will display as an individual heading during the presentation. #+BEGIN_SRC emacs-lisp - (when (require 'org-tree-slide nil t) - (global-set-key (kbd "") 'org-tree-slide-mode) - (global-set-key (kbd "S-") 'org-tree-slide-skip-done-toggle) - (define-key org-tree-slide-mode-map (kbd "") - 'org-tree-slide-move-previous-tree) - (define-key org-tree-slide-mode-map (kbd "") - 'org-tree-slide-move-next-tree) - (define-key org-tree-slide-mode-map (kbd "") - 'org-tree-slide-content) - (setq org-tree-slide-skip-outline-level 4) - (org-tree-slide-narrowing-control-profile) - (setq org-tree-slide-skip-done nil)) +(when (require 'org-tree-slide nil t) + (global-set-key (kbd "") 'org-tree-slide-mode) + (global-set-key (kbd "S-") 'org-tree-slide-skip-done-toggle) + (define-key org-tree-slide-mode-map (kbd "") + 'org-tree-slide-move-previous-tree) + (define-key org-tree-slide-mode-map (kbd "") + 'org-tree-slide-move-next-tree) + (define-key org-tree-slide-mode-map (kbd "") + 'org-tree-slide-content) + (setq org-tree-slide-skip-outline-level 4) + (org-tree-slide-narrowing-control-profile) + (setq org-tree-slide-skip-done nil)) #+END_SRC *** Comments @@ -3993,15 +3989,15 @@ presentation. Some keybindings are also related to comment editing, in particular using outorg. Let’s first declare the dedicated prefix: #+BEGIN_SRC emacs-lisp - (spacemacs/declare-prefix "oc" "comments") +(spacemacs/declare-prefix "oc" "comments") #+END_SRC Now, let’s declare the following keybindings: #+BEGIN_SRC emacs-lisp - (spacemacs/set-leader-keys - "occ" 'outorg-copy-edits-and-exit - "oce" 'outorg-edit-as-org - "oco" 'outline-minor-mode) +(spacemacs/set-leader-keys + "occ" 'outorg-copy-edits-and-exit + "oce" 'outorg-edit-as-org + "oco" 'outline-minor-mode) #+END_SRC ~oco~ enables the outline minor mode, which then allows for the edition of @@ -4017,23 +4013,23 @@ parenthesis which will enable or disable ~dired-hide-details-mode~. On the other hand, a closing parenthesis will show git information in the current Dired buffer. #+BEGIN_SRC emacs-lisp - (define-key dired-mode-map (kbd "(") 'dired-hide-details-mode) - (define-key dired-mode-map (kbd ")") 'dired-git-info-mode) +(define-key dired-mode-map (kbd "(") 'dired-hide-details-mode) +(define-key dired-mode-map (kbd ")") 'dired-git-info-mode) #+END_SRC Something I use from time to time is ~S-F1~ for opening dired in my ~$HOME~ directory. For that, I simply did the following: #+BEGIN_SRC emacs-lisp - (global-set-key (kbd "") (lambda () (interactive) (dired "~/"))) +(global-set-key (kbd "") (lambda () (interactive) (dired "~/"))) #+END_SRC A couple of other useful utilities, sach as opening all marked files, sorting files, opening them externally and renaming them, are also bound to a simple key press: #+BEGIN_SRC emacs-lisp - (define-key dired-mode-map (kbd "f") 'phundrak-open-marked-files) - (define-key dired-mode-map (kbd "F") 'xah/open-in-external-app) - (define-key dired-mode-map (kbd "s") 'xah/dired-sort) +(define-key dired-mode-map (kbd "f") 'phundrak-open-marked-files) +(define-key dired-mode-map (kbd "F") 'xah/open-in-external-app) +(define-key dired-mode-map (kbd "s") 'xah/dired-sort) #+END_SRC *** Files @@ -4041,8 +4037,8 @@ press: :CUSTOM_ID: User_Configuration-Shortcuts-Files-206c2126 :END: #+BEGIN_SRC emacs-lisp - (spacemacs/declare-prefix "of" "open org file") - (spacemacs/set-leader-keys "of" 'phundrak-find-org-files) +(spacemacs/declare-prefix "of" "open org file") +(spacemacs/set-leader-keys "of" 'phundrak-find-org-files) #+END_SRC I also have a shortcut for ~helm-locate~ in case I need to find a file that is @@ -4051,8 +4047,8 @@ doesn’t matter from where I call it, it will find any file on my system that matches the query, whereas ~helm-find~ will only search in the current directory and its subdirectories. This time, the declaration is much simpler: #+BEGIN_SRC emacs-lisp - (spacemacs/declare-prefix "oF" "locate file") - (spacemacs/set-leader-keys "oF" 'helm-locate) +(spacemacs/declare-prefix "oF" "locate file") +(spacemacs/set-leader-keys "oF" 'helm-locate) #+END_SRC And that’s it! This should list all my org files under these directories and @@ -4066,18 +4062,18 @@ the file I want to open and it should open without any issue. Just to make it easier to launch it, I’ll declare a shortcut for launching tetris (which is built into Emacs). #+BEGIN_SRC emacs-lisp - (spacemacs/declare-prefix "oat" "tetris") - (spacemacs/set-leader-keys "oat" 'tetris) +(spacemacs/declare-prefix "oat" "tetris") +(spacemacs/set-leader-keys "oat" 'tetris) #+END_SRC Apparently, no evil keybindings are set for Tetris. Let’s declare them (adapted to the bépo layout): #+BEGIN_SRC emacs-lisp - (require 'tetris) - (define-key tetris-mode-map (kbd "c") 'tetris-move-left) - (define-key tetris-mode-map (kbd "t") 'tetris-move-down) - (define-key tetris-mode-map (kbd "s") 'tetris-rotate-prev) - (define-key tetris-mode-map (kbd "r") 'tetris-move-right) +(require 'tetris) +(define-key tetris-mode-map (kbd "c") 'tetris-move-left) +(define-key tetris-mode-map (kbd "t") 'tetris-move-down) +(define-key tetris-mode-map (kbd "s") 'tetris-rotate-prev) +(define-key tetris-mode-map (kbd "r") 'tetris-move-right) #+END_SRC *** Multiple cursors @@ -4088,16 +4084,16 @@ I don’t really like Spacemacs’ layer for MultipleCursors, so I prefer to sim install the package and create shortcuts for it myself. Let’s first declare category: #+BEGIN_SRC emacs-lisp - (spacemacs/declare-prefix "om" "multiple-cursors") +(spacemacs/declare-prefix "om" "multiple-cursors") #+END_SRC Now, let’s declare the shortcuts related to multiple-cursors: #+BEGIN_SRC emacs-lisp - (spacemacs/set-leader-keys - "ome" 'mc/edit-lines - "omn" 'mc/mark-next-like-this - "omp" 'mc/mark-previous-like-this - "oma" 'mc/mark-all-like-this) +(spacemacs/set-leader-keys + "ome" 'mc/edit-lines + "omn" 'mc/mark-next-like-this + "omp" 'mc/mark-previous-like-this + "oma" 'mc/mark-all-like-this) #+END_SRC *** Org-mode @@ -4106,24 +4102,24 @@ Now, let’s declare the shortcuts related to multiple-cursors: :END: Now, onto some shortcuts related to org-mode. Let’s first declare the category: #+BEGIN_SRC emacs-lisp - (spacemacs/declare-prefix-for-mode 'org-mode "mo" "custom" "User-defined keybindings") - (spacemacs/declare-prefix-for-mode 'org-mode "mot" "toggle" "Toggle org elements") - (spacemacs/declare-prefix-for-mode 'org-mode "moT" "tables") +(spacemacs/declare-prefix-for-mode 'org-mode "mo" "custom" "User-defined keybindings") +(spacemacs/declare-prefix-for-mode 'org-mode "mot" "toggle" "Toggle org elements") +(spacemacs/declare-prefix-for-mode 'org-mode "moT" "tables") #+END_SRC #+BEGIN_SRC emacs-lisp - (spacemacs/set-leader-keys-for-major-mode 'org-mode "ob" 'phundrak-blog-publish) - (spacemacs/declare-prefix-for-mode 'org-mode "ob" "publish blog") +(spacemacs/set-leader-keys-for-major-mode 'org-mode "ob" 'phundrak-blog-publish) +(spacemacs/declare-prefix-for-mode 'org-mode "ob" "publish blog") #+END_SRC Now, I have a couple of shortcuts I use regularly: #+BEGIN_SRC emacs-lisp - (spacemacs/set-leader-keys-for-major-mode 'org-mode - "os" 'org-insert-structure-template - "ots" 'phundrak/toggle-org-src-window-split - "ott" 'org-sidebar-tree) - (spacemacs/declare-prefix-for-mode 'org-mode "moS" "insert template") - (spacemacs/declare-prefix-for-mode 'org-mode "mots" "toggle src split") +(spacemacs/set-leader-keys-for-major-mode 'org-mode + "os" 'org-insert-structure-template + "ots" 'phundrak/toggle-org-src-window-split + "ott" 'org-sidebar-tree) +(spacemacs/declare-prefix-for-mode 'org-mode "moS" "insert template") +(spacemacs/declare-prefix-for-mode 'org-mode "mots" "toggle src split") #+END_SRC ~os~ allows me to insert an org structure template defined in @@ -4132,7 +4128,7 @@ outline of the current org file. ~oT~ is the prefix for tree-related operations: #+BEGIN_SRC emacs-lisp - (spacemacs/declare-prefix-for-mode 'org-mode "moT" "tables") +(spacemacs/declare-prefix-for-mode 'org-mode "moT" "tables") #+END_SRC These shortcuts allow to manipulate the width of the column the cursor is @@ -4140,21 +4136,21 @@ currently in, by either shrinking it, expanding it, or toggling its state between shrunk or expanded. A prefix for all of these commands has been also added in order to make the purpose of the shortcuts clearer. #+BEGIN_SRC emacs-lisp - (spacemacs/set-leader-keys-for-major-mode 'org-mode - "oTt" 'org-table-toggle-column-width - "oTe" 'org-table-expand - "oTs" 'org-table-shrink) - (spacemacs/declare-prefix-for-mode 'org-mode "moTt" "toggle width") - (spacemacs/declare-prefix-for-mode 'org-mode "moTe" "expand") - (spacemacs/declare-prefix-for-mode 'org-mode "moTs" "shrink") +(spacemacs/set-leader-keys-for-major-mode 'org-mode + "oTt" 'org-table-toggle-column-width + "oTe" 'org-table-expand + "oTs" 'org-table-shrink) +(spacemacs/declare-prefix-for-mode 'org-mode "moTt" "toggle width") +(spacemacs/declare-prefix-for-mode 'org-mode "moTe" "expand") +(spacemacs/declare-prefix-for-mode 'org-mode "moTs" "shrink") #+END_SRC Finaly, I set the following shortcut in order to easily remove ~RESULTS~ blocks from org source code blocks: #+BEGIN_SRC emacs-lisp - (spacemacs/set-leader-keys-for-major-mode 'org-mode - "or" 'org-babel-remove-result-one-or-many) - (spacemacs/declare-prefix-for-mode 'org-mode "mor" "remove org result") +(spacemacs/set-leader-keys-for-major-mode 'org-mode + "or" 'org-babel-remove-result-one-or-many) +(spacemacs/declare-prefix-for-mode 'org-mode "mor" "remove org result") #+END_SRC *** Toggle @@ -4163,7 +4159,7 @@ from org source code blocks: :END: This category allows to toggle some modes and options. #+BEGIN_SRC emacs-lisp - (spacemacs/declare-prefix "ot" "toggle") +(spacemacs/declare-prefix "ot" "toggle") #+END_SRC As you can see, I have here four shortcuts for toggling various elements in @@ -4180,12 +4176,12 @@ Emacs: - ~otS~ :: toggles whether or not Eshell should shorten the current path in its prompt #+BEGIN_SRC emacs-lisp - (spacemacs/set-leader-keys - "otb" 'fancy-battery-mode - "otd" 'elcord-mode - "otf" 'flycheck-mode - "ots" 'prettify-symbols-mode - "otS" 'phundrak-prompt-toggle-abbreviation) +(spacemacs/set-leader-keys + "otb" 'fancy-battery-mode + "otd" 'elcord-mode + "otf" 'flycheck-mode + "ots" 'prettify-symbols-mode + "otS" 'phundrak-prompt-toggle-abbreviation) #+END_SRC We also have some input methods-related shortcuts in a sub-category: ~oti~. The @@ -4193,23 +4189,23 @@ first shortcuts below are used to either toggle between no input method or the last one used (~otit~), or choose an input method among the various available ones from Emacs (~otis~). #+BEGIN_SRC emacs-lisp - (spacemacs/declare-prefix "oti" "input methods") - (spacemacs/set-leader-keys - "otit" 'toggle-input-method - "otis" 'set-input-method) +(spacemacs/declare-prefix "oti" "input methods") +(spacemacs/set-leader-keys + "otit" 'toggle-input-method + "otis" 'set-input-method) #+END_SRC The shortcuts below though allow me to directly switch to one of these three known input methods I sometimes or often use, namely Japanese, Tibetan and IPA (by typing in X-SAMPA). #+BEGIN_SRC emacs-lisp - (spacemacs/declare-prefix "otij" "Japanese") - (spacemacs/declare-prefix "otix" "IPA (X-SAMPA)") - (spacemacs/declare-prefix "otiT" "Tibetan") - (spacemacs/set-leader-keys - "otij" (lambda () (interactive) (set-input-method 'japanese)) - "otix" (lambda () (interactive) (set-input-method 'ipa-x-sampa)) - "otiT" (lambda () (interactive) (set-input-method 'tibetan-wylie))) +(spacemacs/declare-prefix "otij" "Japanese") +(spacemacs/declare-prefix "otix" "IPA (X-SAMPA)") +(spacemacs/declare-prefix "otiT" "Tibetan") +(spacemacs/set-leader-keys + "otij" (lambda () (interactive) (set-input-method 'japanese)) + "otix" (lambda () (interactive) (set-input-method 'ipa-x-sampa)) + "otiT" (lambda () (interactive) (set-input-method 'tibetan-wylie))) #+END_SRC ** Mu4e @@ -4230,13 +4226,13 @@ Due to mu sitting on top of a maildir, I need to tell mu4e where said maildir is, and point it the trash, archive, and sent folders as well as the refresh command and how frequently I want my emails to be refreshed. #+BEGIN_SRC emacs-lisp - (setq mu4e-maildir "~/.mail" - mu4e-trash-folder "/Trash" - mu4e-refile-folder "/Archive" - mu4e-sent-folder "/Sent" - mu4e-drafts-folder "/Drafts" - mu4e-get-mail-command "mbsync -a" - mu4e-update-interval 60) +(setq mu4e-maildir "~/.mail" + mu4e-trash-folder "/Trash" + mu4e-refile-folder "/Archive" + mu4e-sent-folder "/Sent" + mu4e-drafts-folder "/Drafts" + mu4e-get-mail-command "mbsync -a" + mu4e-update-interval 60) #+END_SRC This source block is an example of the search queries in mu4e, and part of the @@ -4246,41 +4242,41 @@ with modern Email client (and often you don’t even get them). All these bookmarks can be accessed through a shortcut on the main mu4e buffer, prefixed by ~b~. So, for instance, my unread messages are accessed through ~bU~. #+BEGIN_SRC emacs-lisp - (setq mu4e-bookmarks - `((,(s-join " " - '("NOT flag:trashed" - "AND (maildir:/Inbox OR maildir:/Junk)" - "AND NOT to:CONLANG@LISTSERV.BROWN.EDU" - "AND NOT to:AUXLANG@LISTSERV.BROWN.EDU" - "AND NOT to:ateliers-emacs@framalistes.org" - "AND NOT to:ateliers-paris@emacs-doctor.com" - "AND NOT list:ateliers-emacs.framalistes.org" - "AND NOT list:ateliers-paris.emacs-doctor.com")) - "Inbox" ?i) ;; Inbox without the linguistics mailing lists - (,(s-join " " - '("NOT flag:trashed" - "AND (maildir:/Inbox OR maildir:/Junk)" - "AND (f:/.*up8\.edu|.*univ-paris8.*/" - "OR c:/.*up8\.edu|.*univ-paris8.*/" - "OR t:/.*up8\.edu|.*univ-paris8.*/)")) - "University" ?u) ;; University-related emails - (,(s-join " " - '("to:CONLANG@LISTSERV.BROWN.EDU" - "OR to:AUXLANG@LISTSERV.BROWN.EDU")) - "Linguistics" ?l) ;; linguistics mailing lists - (,(s-join " " - '("list:ateliers-emacs.framalistes.org" - "OR to:ateliers-paris@emacs-doctor.com" - "OR list:ateliers-paris.emacs-doctor.com")) - "Emacs" ?e) ;; Emacs mailing list - ("maildir:/Sent" "Sent messages" ?s) - ("flag:unread AND NOT flag:trashed" "Unread messages" ?U) - ("date:today..now AND NOT flag:trashed" "Today's messages" ?t) - ("date:7d..now AND NOT flag:trashed" "Last 7 days" ?w) - ("date:1m..now AND NOT flag:trashed" "Last month" ?m) - ("date:1y..now AND NOT flag:trashed" "Last year" ?y) - ("flag:trashed AND NOT flag:trashed" "Trash" ?T) - ("mime:image/* AND NOT flag:trashed" "Messages with images" ?p))) +(setq mu4e-bookmarks + `((,(s-join " " + '("NOT flag:trashed" + "AND (maildir:/Inbox OR maildir:/Junk)" + "AND NOT to:CONLANG@LISTSERV.BROWN.EDU" + "AND NOT to:AUXLANG@LISTSERV.BROWN.EDU" + "AND NOT to:ateliers-emacs@framalistes.org" + "AND NOT to:ateliers-paris@emacs-doctor.com" + "AND NOT list:ateliers-emacs.framalistes.org" + "AND NOT list:ateliers-paris.emacs-doctor.com")) + "Inbox" ?i) ;; Inbox without the linguistics mailing lists + (,(s-join " " + '("NOT flag:trashed" + "AND (maildir:/Inbox OR maildir:/Junk)" + "AND (f:/.*up8\.edu|.*univ-paris8.*/" + "OR c:/.*up8\.edu|.*univ-paris8.*/" + "OR t:/.*up8\.edu|.*univ-paris8.*/)")) + "University" ?u) ;; University-related emails + (,(s-join " " + '("to:CONLANG@LISTSERV.BROWN.EDU" + "OR to:AUXLANG@LISTSERV.BROWN.EDU")) + "Linguistics" ?l) ;; linguistics mailing lists + (,(s-join " " + '("list:ateliers-emacs.framalistes.org" + "OR to:ateliers-paris@emacs-doctor.com" + "OR list:ateliers-paris.emacs-doctor.com")) + "Emacs" ?e) ;; Emacs mailing list + ("maildir:/Sent" "Sent messages" ?s) + ("flag:unread AND NOT flag:trashed" "Unread messages" ?U) + ("date:today..now AND NOT flag:trashed" "Today's messages" ?t) + ("date:7d..now AND NOT flag:trashed" "Last 7 days" ?w) + ("date:1m..now AND NOT flag:trashed" "Last month" ?m) + ("date:1y..now AND NOT flag:trashed" "Last year" ?y) + ("flag:trashed AND NOT flag:trashed" "Trash" ?T) + ("mime:image/* AND NOT flag:trashed" "Messages with images" ?p))) #+END_SRC On new email arrival, Emacs can send the system a notification which will be @@ -4288,57 +4284,57 @@ handled as any other notification received by the system and will display the number of unread emails to the user; in my case, notifications are handled by AwesomeWM. #+BEGIN_SRC emacs-lisp - (setq mu4e-enable-notifications t - mu4e-alert-email-notification-types '(count)) - (with-eval-after-load 'mu4e-alert - (mu4e-alert-set-default-style 'notifications)) - (add-hook 'mu4e-view-mode-hook 'visual-line-mode) +(setq mu4e-enable-notifications t + mu4e-alert-email-notification-types '(count)) +(with-eval-after-load 'mu4e-alert + (mu4e-alert-set-default-style 'notifications)) +(add-hook 'mu4e-view-mode-hook 'visual-line-mode) #+END_SRC This is the setup I have for my SMTP mail server: I point Emacs’ SMTP services to my private mail server on its SMTP port, which should be used with a STARTTLS stream. And I tell Emacs this is the default way to send an email. #+BEGIN_SRC emacs-lisp - (setq smtpmail-smtp-server "mail.phundrak.com" - smtpmail-smtp-service 587 - smtpmail-stream-type 'starttls - message-send-mail-function 'smtpmail-send-it) +(setq smtpmail-smtp-server "mail.phundrak.com" + smtpmail-smtp-service 587 + smtpmail-stream-type 'starttls + message-send-mail-function 'smtpmail-send-it) #+END_SRC I wish my emails to be signed by default using PGP/MIME. ~mu4e~ uses ~message~ for composing new emails, so I simply need to add the function that will add the signature to emails to the hook called when creating a new email. #+BEGIN_SRC emacs-lisp - (add-hook 'mu4e-compose-mode-hook 'mml-secure-message-sign-pgpmime) +(add-hook 'mu4e-compose-mode-hook 'mml-secure-message-sign-pgpmime) #+END_SRC mu4e used to be able to export emails to PDFs, but unfortunately this possibility was discontinued. But we can (sort of) bring it back! #+BEGIN_SRC emacs-lisp - (defun mu4e-action-open-as-pdf (msg) - "Export and open as PDF a mu4e `MSG'" - (let* ((date (mu4e-message-field msg :date)) - (infile (mu4e~write-body-to-html msg)) - (outfile (format-time-string "/tmp/%Y-%m-%d%H%M%S.pdf" date))) - (with-temp-buffer - (shell-command - (format "wkhtmltopdf %s %s" infile outfile) t)) - (find-file outfile))) +(defun mu4e-action-open-as-pdf (msg) + "Export and open as PDF a mu4e `MSG'" + (let* ((date (mu4e-message-field msg :date)) + (infile (mu4e~write-body-to-html msg)) + (outfile (format-time-string "/tmp/%Y-%m-%d%H%M%S.pdf" date))) + (with-temp-buffer + (shell-command + (format "wkhtmltopdf %s %s" infile outfile) t)) + (find-file outfile))) - (add-to-list 'mu4e-view-actions '("PDF view" . mu4e-action-open-as-pdf) t) +(add-to-list 'mu4e-view-actions '("PDF view" . mu4e-action-open-as-pdf) t) #+END_SRC Lastly, some emails are better displayed in a browser than in Emacs. My Emacs build has the webkit browser enabled, so I’ll add an option to open with it emails. #+BEGIN_SRC emacs-lisp - (defun phundrak/mu4e-view-in-browser (msg) - (xwidget-webkit-browse-url (concat "file://" - (mu4e~write-body-to-html msg)))) +(defun phundrak/mu4e-view-in-browser (msg) + (xwidget-webkit-browse-url (concat "file://" + (mu4e~write-body-to-html msg)))) - (add-to-list 'mu4e-view-actions - '("Xwidget Webkit Browser" . phundrak/mu4e-view-in-browser) - t) +(add-to-list 'mu4e-view-actions + '("Xwidget Webkit Browser" . phundrak/mu4e-view-in-browser) + t) #+END_SRC *** Visual Configuration @@ -4349,10 +4345,10 @@ The following also allows me to automatically include my signature in my Emails, to view images in my Emacs buffers and to show me the address of my contacts and not just their names. #+BEGIN_SRC emacs-lisp - (setq mu4e-compose-signature-auto-include t - mu4e-view-show-images t - mu4e-view-prefer-html t - mu4e-view-show-addresses t) +(setq mu4e-compose-signature-auto-include t + mu4e-view-show-images t + mu4e-view-prefer-html t + mu4e-view-show-addresses t) #+END_SRC Now this hook is added so I can get a maximal width for the text of my emails, I @@ -4360,32 +4356,32 @@ really don’t like it when lines are kilometers long. I would like instead to hook ~visual-line-mode~ and ~auto-fill-mode~, but for some reasons Emacs throws an error when I add them, So I go with ~visual-fill-column-mode~ instead. #+BEGIN_SRC emacs-lisp - (add-hook 'mu4e-view-mode-hook 'visual-fill-column-mode) +(add-hook 'mu4e-view-mode-hook 'visual-fill-column-mode) #+END_SRC Icons are nice and all, but my current font does not display some of the default icons set by mu4e. Due to this, I will define back these icons to the original characters defined by mu4e: #+BEGIN_SRC emacs-lisp - (setq mu4e-headers-draft-mark '("D" . "D") - mu4e-headers-flagged-mark '("F" . "F") - mu4e-headers-new-mark '("N" . "N") - mu4e-headers-passed-mark '("P" . "P") - mu4e-headers-replied-mark '("R" . "R") - mu4e-headers-seen-mark '("S" . "S") - mu4e-headers-trashed-mark '("T" . "T") - mu4e-headers-attach-mark '("a" . "a") - mu4e-headers-encrypted-mark '("x" . "x") - mu4e-headers-signed-mark '("s" . "s") - mu4e-headers-unread-mark '("u" . "u")) +(setq mu4e-headers-draft-mark '("D" . "D") + mu4e-headers-flagged-mark '("F" . "F") + mu4e-headers-new-mark '("N" . "N") + mu4e-headers-passed-mark '("P" . "P") + mu4e-headers-replied-mark '("R" . "R") + mu4e-headers-seen-mark '("S" . "S") + mu4e-headers-trashed-mark '("T" . "T") + mu4e-headers-attach-mark '("a" . "a") + mu4e-headers-encrypted-mark '("x" . "x") + mu4e-headers-signed-mark '("s" . "s") + mu4e-headers-unread-mark '("u" . "u")) #+END_SRC I don’t like the American time format. I really don’t. I prefer much more something more standard, like ISO8601 standard. Not exactly ISO8601, but close to it. Also, fuck the paywalls imposed by ISO. #+BEGIN_SRC emacs-lisp - (setq mu4e-view-date-format "%Y-%m-%d %R" - mu4e-headers-date-format "%Y-%m-%d") +(setq mu4e-view-date-format "%Y-%m-%d %R" + mu4e-headers-date-format "%Y-%m-%d") #+END_SRC *** Misc @@ -4397,7 +4393,7 @@ discourage mu4e from reading rich text emails and instead open them as plain text. However, I do not wish to discourage opening HTML emails since I can open them in the browser. #+BEGIN_SRC emacs-lisp - (setq mm-discouraged-alternatives '("text/richtext")) +(setq mm-discouraged-alternatives '("text/richtext")) #+END_SRC ** Miscellaneous @@ -4409,15 +4405,15 @@ category, so I’ll collect them here. I have this regexp for detecting paragraphs. #+BEGIN_SRC emacs-lisp - (setq paragraph-start "\f\\|[ \t]*$\\|[ \t]*[-+*] ") +(setq paragraph-start "\f\\|[ \t]*$\\|[ \t]*[-+*] ") #+END_SRC And this variable for Elcord so the main icon displayed in Discord is the icon representing the current major-mode. I also don’t want to display the small icon, so let’s get rid of that. #+BEGIN_SRC emacs-lisp - (setq elcord-use-major-mode-as-main-icon t - elcord-show-small-icon nil) +(setq elcord-use-major-mode-as-main-icon t + elcord-show-small-icon nil) #+END_SRC *** Pinentry @@ -4437,8 +4433,8 @@ it so: Thanks to the wttrin package, I can get the weather forecast in Emacs for a couple of cities. I just need to specify them to Emacs like so: #+BEGIN_SRC emacs-lisp - (setq wttrin-default-cities '("Aubervilliers" "Paris" "Lyon" "Nonières" - "Saint Agrève")) +(setq wttrin-default-cities '("Aubervilliers" "Paris" "Lyon" "Nonières" + "Saint Agrève")) #+END_SRC However, the package is currently broken (it was last updated in 2017): wttr.in @@ -4446,19 +4442,19 @@ now returns by default an HTML page instead of an ASCII result. In order to fix it, a ~?A~ must be added at the end of the request in order to get a nice output. Also, let’s use the HTTPS protocol while we’re at it. #+BEGIN_SRC emacs-lisp - (defun wttrin-fetch-raw-string (query) - "Get the weather information based on your QUERY." - (let ((url-user-agent "curl")) - (add-to-list 'url-request-extra-headers wttrin-default-accept-language) - (with-current-buffer - (url-retrieve-synchronously - (format "http%s://wttr.in/%s?A" - (if (gnutls-available-p) "s" "") - query) - (lambda (status) - (switch-to-buffer (current-buffer)))) - (decode-coding-string (buffer-string) - 'utf-8)))) +(defun wttrin-fetch-raw-string (query) + "Get the weather information based on your QUERY." + (let ((url-user-agent "curl")) + (add-to-list 'url-request-extra-headers wttrin-default-accept-language) + (with-current-buffer + (url-retrieve-synchronously + (format "http%s://wttr.in/%s?A" + (if (gnutls-available-p) "s" "") + query) + (lambda (status) + (switch-to-buffer (current-buffer)))) + (decode-coding-string (buffer-string) + 'utf-8)))) #+END_SRC ** Nov-mode @@ -4468,23 +4464,23 @@ output. Also, let’s use the HTTPS protocol while we’re at it. ~nov-mode~ is the mode used in the Epub reader. Here I will write a little function that I will call through a hook each time I’m opening a new EPUB file. #+BEGIN_SRC emacs-lisp - (defun my-nov-font-setup () - (face-remap-add-relative 'variable-pitch :family "Charis SIL" - :size 16 - :height 1.0)) +(defun my-nov-font-setup () + (face-remap-add-relative 'variable-pitch :family "Charis SIL" + :size 16 + :height 1.0)) #+END_SRC Let’s bind this function to the ~nov-mode~ hook. By the way, we’ll also enable the ~visual-line-mode~ here, just in case. #+BEGIN_SRC emacs-lisp - (mapc (lambda (mode) - (add-hook 'nov-mode-hook mode)) - '('my-nov-font-setup 'visual-line-mode)) +(mapc (lambda (mode) + (add-hook 'nov-mode-hook mode)) + '('my-nov-font-setup 'visual-line-mode)) #+END_SRC Let’s also set the maximum length of the lines in ~nov-mode~: #+BEGIN_SRC emacs-lisp - (setq nov-text-width 80) +(setq nov-text-width 80) #+END_SRC ** Programming @@ -4500,21 +4496,21 @@ default that I want to use, especially some modes I want to take advantage of. This is why I enable first the ~lsp-treemacs-sync-mode~ so treemacs is LSP aware: #+BEGIN_SRC emacs-lisp - (lsp-treemacs-sync-mode 1) +(lsp-treemacs-sync-mode 1) #+END_SRC I also enable some layers related to ~dap~, the Debug Adapter Protocol, which works really nicely with LSP. Let’s enable Dap’s modes: #+BEGIN_SRC emacs-lisp - (dap-mode 1) - (dap-ui-mode 1) - (dap-tooltip-mode 1) +(dap-mode 1) +(dap-ui-mode 1) +(dap-tooltip-mode 1) #+END_SRC Finally, I also want the documentation tooltip to show up when the cursor is above a documented piece of code or symbol. Let’s enable that too: #+BEGIN_SRC emacs-lisp - (tooltip-mode 1) +(tooltip-mode 1) #+END_SRC *** ASM configuration @@ -4524,12 +4520,12 @@ above a documented piece of code or symbol. Let’s enable that too: The first thing I will set with my ASM configuration is where the reference PDF is located. #+BEGIN_SRC emacs-lisp - (setq x86-lookup-pdf "~/Documents/code/asm/Intelx86/325383-sdm-vol-2abcd.pdf") +(setq x86-lookup-pdf "~/Documents/code/asm/Intelx86/325383-sdm-vol-2abcd.pdf") #+END_SRC I will also modify what the comment character is, from a ~;~ to a ~#~: #+BEGIN_SRC emacs-lisp - (setq asm-comment-char ?\#) +(setq asm-comment-char ?\#) #+END_SRC *** C/C++ @@ -4539,12 +4535,12 @@ I will also modify what the comment character is, from a ~;~ to a ~#~: As the C/C++ syntax is checked by flycheck, let’s make sure we are using the latest standard available, that is C++17 and C17, from Clang. #+BEGIN_SRC emacs-lisp - (add-hook 'c-mode-hook - (lambda () - (setq flycheck-clang-language-standard "c17"))) - (add-hook 'c++-mode-hook - (lambda () - (setq flycheck-clang-language-standard "c++17"))) +(add-hook 'c-mode-hook + (lambda () + (setq flycheck-clang-language-standard "c17"))) +(add-hook 'c++-mode-hook + (lambda () + (setq flycheck-clang-language-standard "c++17"))) #+END_SRC *** Dart configuration @@ -4555,19 +4551,19 @@ For Dart, I mainly declared some custom shortcuts bound to ~dart-mode~ related to flutter, so nothing too exciting here. Some prefix are declared in order to avoid the shortcuts in helm to show up as just ~custom~. #+begin_src emacs-lisp - (spacemacs/declare-prefix-for-mode 'dart-mode "mo" "user-defined") - (spacemacs/declare-prefix-for-mode 'dart-mode "mof" "flutter") - (spacemacs/declare-prefix-for-mode 'dart-mode "mofr" "flutter-run") +(spacemacs/declare-prefix-for-mode 'dart-mode "mo" "user-defined") +(spacemacs/declare-prefix-for-mode 'dart-mode "mof" "flutter") +(spacemacs/declare-prefix-for-mode 'dart-mode "mofr" "flutter-run") #+end_src Now, for the shortcuts themselves: #+BEGIN_SRC emacs-lisp - (spacemacs/set-leader-keys-for-major-mode 'dart-mode - "ofH" 'flutter-hot-restart - "ofh" 'flutter-hot-reload - "ofq" 'flutter-quit - "ofr" (lambda () (interactive) (flutter-run "-v")) - "ofs" 'flutter-screenshot) +(spacemacs/set-leader-keys-for-major-mode 'dart-mode + "ofH" 'flutter-hot-restart + "ofh" 'flutter-hot-reload + "ofq" 'flutter-quit + "ofr" (lambda () (interactive) (flutter-run "-v")) + "ofs" 'flutter-screenshot) #+END_SRC *** Emacs Lisp @@ -4585,7 +4581,7 @@ By default, if some Elisp code is opened, I want to enable ~eldoc-mode~ so I can easily get some documentation on the symbols in the source code. This is done via the use of hooks. #+BEGIN_SRC emacs-lisp - (add-hook 'prog-mode-hook 'eldoc-mode) +(add-hook 'prog-mode-hook 'eldoc-mode) #+END_SRC **** ~phundrak/write-to-buffer~ @@ -4596,19 +4592,19 @@ I was very surprised when I discovered no such function exists in Elisp. This function basically writes a string into a buffer, and optionally switches the user to the buffer. Here is the code for that function: #+BEGIN_SRC elisp :results silent - (defun write-to-buffer ($input-string $outputbuf &optional $switchbuf) - "Writes `$input-string' to the specified `output-buffer'. If - `switch-buffer' is non-nil, the active buffer will switch to the - output buffer; otherwise, it will take the user back to their - initial buffer. Works with `$input-string' as a string or a list - of strings." - (let ((oldbuf (current-buffer))) - (switch-to-buffer $outputbuf) - (cond ((char-or-string-p $input-string) (insert $input-string)) - ((listp $input-string) (dolist (elem $input-string) - (insert (format "%s\n" elem))))) - (unless $switchbuf - (switch-to-buffer oldbuf)))) +(defun write-to-buffer ($input-string $outputbuf &optional $switchbuf) + "Writes `$input-string' to the specified `output-buffer'. If +`switch-buffer' is non-nil, the active buffer will switch to the +output buffer; otherwise, it will take the user back to their +initial buffer. Works with `$input-string' as a string or a list +of strings." + (let ((oldbuf (current-buffer))) + (switch-to-buffer $outputbuf) + (cond ((char-or-string-p $input-string) (insert $input-string)) + ((listp $input-string) (dolist (elem $input-string) + (insert (format "%s\n" elem))))) + (unless $switchbuf + (switch-to-buffer oldbuf)))) #+END_SRC *** Python @@ -4617,7 +4613,7 @@ user to the buffer. Here is the code for that function: :END: Emacs throws me an error about the python interpreter, let’s silence it: #+BEGIN_SRC emacs-lisp - (setq python-shell-completion-native-disabled-interpreters '("python")) +(setq python-shell-completion-native-disabled-interpreters '("python")) #+END_SRC *** Rust @@ -4628,38 +4624,38 @@ I need to point to racer where the source code of Rust is located so I can get some documentation. This is installed with the ~rust-src~ component you can get through ~rustup~. To install it, simply run #+BEGIN_SRC sh :tangle no :exports code - rustup component add rust-src +rustup component add rust-src #+END_SRC Now, the source code for Rust should be included in your installation. I personally prefer to develop with Rust stable, so let’s indicate to Emacs to search for documentation in the stable sources: #+BEGIN_SRC emacs-lisp - (setq racer-rust-src-path - "~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src") +(setq racer-rust-src-path + "~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src") #+END_SRC Rust’s default ~cargo check~ command is already very good, however I also enjoy getting some more hints while developping, and ~clippy~ does a very good job at it. To get clippy, I need to run the following to install it: #+BEGIN_SRC sh :tangle no :exports code - rustup compontent add clippy +rustup compontent add clippy #+END_SRC And this will get it installed with all of my Rust toolchain, and it will be updated with it. Now, let’s indicate LSP that I want to use that instead of ~check~: #+BEGIN_SRC emacs-lisp - (setq lsp-rust-analyzer-cargo-watch-command "clippy") +(setq lsp-rust-analyzer-cargo-watch-command "clippy") #+END_SRC Finally, I wish to enable ~electric-pair-mode~ and ~indent-guide-mode~ for Rust files, so let’s enable that through the use of a hook: #+BEGIN_SRC emacs-lisp :tangle no - (add-hook 'rust-mode-hook - '(lambda () - (local-set-key (kbd "TAB") #'company-indent-or-complete-common) - (electric-pair-mode 1))) +(add-hook 'rust-mode-hook + '(lambda () + (local-set-key (kbd "TAB") #'company-indent-or-complete-common) + (electric-pair-mode 1))) #+END_SRC *** Scheme @@ -4669,7 +4665,7 @@ files, so let’s enable that through the use of a hook: The Scheme configuration will be very short, I just need to tell Emacs the name of the interpreter since it is not the default one: #+BEGIN_SRC emacs-lisp - (setq geiser-chicken-binary "chicken-csi") +(setq geiser-chicken-binary "chicken-csi") #+END_SRC ** Projectile @@ -4686,8 +4682,8 @@ make Emacs ignore all ~node_modules~ directories it could encounter. And for some reason, =~/.emacs.spacemacs= is always in my projects list (I now use XDG-compliant directories), so let’s also ignore that. #+BEGIN_SRC emacs-lisp - (setq projectile-ignored-projects '("~/.cache/paru" "~/.emacs.spacemacs" "/tmp")) - (add-to-list 'projectile-globally-ignored-directories "node_modules") +(setq projectile-ignored-projects '("~/.cache/paru" "~/.emacs.spacemacs" "/tmp")) +(add-to-list 'projectile-globally-ignored-directories "node_modules") #+END_SRC ** Readers @@ -4700,13 +4696,13 @@ I missed in my Emacs PDF reader from Zathura! I still think Zathura is a fantastic tool, but now my PDF reader in Emacs is almost perfect! I just need to adjust some colors: #+BEGIN_SRC emacs-lisp - (with-eval-after-load 'pdf-view - (setq pdf-view-midnight-colors '("#d8dee9" . "#2e3440"))) +(with-eval-after-load 'pdf-view + (setq pdf-view-midnight-colors '("#d8dee9" . "#2e3440"))) #+END_SRC Let’s also enable dark mode automatically: #+BEGIN_SRC emacs-lisp - (add-hook 'pdf-tools-enabled-hook 'pdf-view-midnight-minor-mode) +(add-hook 'pdf-tools-enabled-hook 'pdf-view-midnight-minor-mode) #+END_SRC And there we go! A beautiful, dark-mode PDF reader inside Emacs! And with @@ -4723,22 +4719,22 @@ that will close any buffer that contains an open ~.gpg~ file –I certainly do n want anyone to be able to read such files on my computer if I leave it even for a couple of minutes. #+BEGIN_SRC emacs-lisp - (defun phundrak/kill-gpg-buffers () - "Kill GPG buffers." - (interactive) - (let ((buffers-killed 0)) - (dolist (buffer (buffer-list)) - (with-current-buffer buffer - (when (string-match ".*\.gpg$" (buffer-name buffer)) - (message "Auto killing .gpg buffer '%s'" (buffer-name buffer)) - (when (buffer-modified-p buffer) - (save-buffer)) - (kill-buffer buffer) - (setq buffers-killed (+ buffers-killed 1))))) - (unless (zerop buffers-killed) - ;; Kill gpg-agent. - (shell-command "gpgconf --kill gpg-agent") - (message "%s .gpg buffers have been autosaved and killed" buffers-killed)))) +(defun phundrak/kill-gpg-buffers () + "Kill GPG buffers." + (interactive) + (let ((buffers-killed 0)) + (dolist (buffer (buffer-list)) + (with-current-buffer buffer + (when (string-match ".*\.gpg$" (buffer-name buffer)) + (message "Auto killing .gpg buffer '%s'" (buffer-name buffer)) + (when (buffer-modified-p buffer) + (save-buffer)) + (kill-buffer buffer) + (setq buffers-killed (+ buffers-killed 1))))) + (unless (zerop buffers-killed) + ;; Kill gpg-agent. + (shell-command "gpgconf --kill gpg-agent") + (message "%s .gpg buffers have been autosaved and killed" buffers-killed)))) #+END_SRC Notice the ~(shell-command "gpgconf --kill gpg-agent")~ command there: it kills @@ -4755,7 +4751,7 @@ to times a bit of a pain, but at least I’m now sure I won’t ever have to wor about someone reading my GPG files open in Emacs while I’m out for a quick break. #+BEGIN_SRC emacs-lisp - (run-with-idle-timer 60 t 'phundrak/kill-gpg-buffers) +(run-with-idle-timer 60 t 'phundrak/kill-gpg-buffers) #+END_SRC ** Snippets @@ -4779,11 +4775,11 @@ Be aware that on top of these custom snippets, I also use the package I have so far two snippets, the first one is actually just a convenience to make it easier to type a ~println!~ macro than the default snippet. #+BEGIN_SRC snippet :tangle ~/.emacs.spacemacs/private/snippets/rust-mode/println - # -*- mode: snippet -*- - # name: println - # key: pln - # -- - println!("${1:{}}", $2); +# -*- mode: snippet -*- +# name: println +# key: pln +# -- +println!("${1:{}}", $2); #+END_SRC The second one is more interesting: it is used to create a ~new~ method for a @@ -4791,16 +4787,16 @@ struct, and it will try to create a function that will assign each argument passed to the method to members of the struct. It relies on the custom function [[#Custom-functions-yas-rust-new-assignments-4ad16bde][I wrote here]]. #+BEGIN_SRC snippet :tangle ~/.emacs.spacemacs/private/snippets/rust-mode/new - # -*- mode: snippet -*- - # name: new - # key: _new - # -- - fn new(${1:args}) -> Self { - $0 - Self { - ${1:$(phundrak-yas-rust-new-assignments yas-text)} - } +# -*- mode: snippet -*- +# name: new +# key: _new +# -- +fn new(${1:args}) -> Self { + $0 + Self { + ${1:$(phundrak-yas-rust-new-assignments yas-text)} } +} #+END_SRC *** Org headers @@ -4811,35 +4807,35 @@ The first two snippets are used to add HTML or LaTeX attributes to elements in org-mode. The third also has a similar usage, inserting a ~#+CAPTION~ header before an element, as well as the fourth which inserts a ~#+NAME~ header. #+BEGIN_SRC snippet :tangle ~/.emacs.spacemacs/private/snippets/org-mode/attr_html - # -*- mode: snippet -*- - # name: ATTR HTML - # key: > +<> - <> +<> - <> +<> - (let* ((makeface (string= "yes" makeface)) - (headers (cadr input)) - (faces (mapcar (lambda (face) - (phundrak-filter (lambda (elem) - (or (numberp (cadr elem)) - (not (string= "" - (cadr elem))))) - (phundrak-zip headers face))) - (cddr input)))) - (mapconcat (lambda (face) - (concat - (format (if makeface "`(%s ((t " "(%s `") - (cadr (assoc "Name" face))) - (format "(%s %s %s %s)" - (if (assoc "additional" face) - (cadr (assoc "additional" face)) - "") - (let ((result "")) - (dolist (property '("inherit" "weight" "height" "foreground" - "background" "underline") - result) - (let ((prop (assoc property face))) - (when prop - (setf result (format "%s :%s %s" - result - property - (if (numberp (cadr prop)) - (number-to-string (cadr prop)) - (cadr prop)))))))) - (if (assoc "font" face) - (format ":font \"%s\"" - (cadr (assoc "font" face))) - "") - (if (assoc "family" face) - (format ":family \"%s\"" - (cadr (assoc "family" face))) - "")) - (if makeface - ")) t)" - ")"))) - faces - "\n")) +(let* ((makeface (string= "yes" makeface)) + (headers (cadr input)) + (faces (mapcar (lambda (face) + (phundrak-filter (lambda (elem) + (or (numberp (cadr elem)) + (not (string= "" + (cadr elem))))) + (phundrak-zip headers face))) + (cddr input)))) + (mapconcat (lambda (face) + (concat + (format (if makeface "`(%s ((t " "(%s `") + (cadr (assoc "Name" face))) + (format "(%s %s %s %s)" + (if (assoc "additional" face) + (cadr (assoc "additional" face)) + "") + (let ((result "")) + (dolist (property '("inherit" "weight" "height" "foreground" + "background" "underline") + result) + (let ((prop (assoc property face))) + (when prop + (setf result (format "%s :%s %s" + result + property + (if (numberp (cadr prop)) + (number-to-string (cadr prop)) + (cadr prop)))))))) + (if (assoc "font" face) + (format ":font \"%s\"" + (cadr (assoc "font" face))) + "") + (if (assoc "family" face) + (format ":family \"%s\"" + (cadr (assoc "family" face))) + "")) + (if makeface + ")) t)" + ")"))) + faces + "\n")) #+END_SRC Sometimes, some visual properties just don’t fit right for me and I need to edit @@ -5110,15 +5106,15 @@ them. This is the case for example for org-mode for which I want to have a mix of fixed and variable pitches. Below you can see the code that does that for me, I’ll get into more detail below this code block. #+BEGIN_SRC emacs-lisp :noweb yes - (let ( - <> - ) - (custom-theme-set-faces - 'user - <> - <> - <> - )) +(let ( + <> + ) + (custom-theme-set-faces + 'user + <> + <> + <> + )) #+END_SRC **** Diff and Magit @@ -5203,7 +5199,7 @@ First here are some common properties that will be reused in faces below: :END: The package ~info-colors~ adds colors to Emacs’ info mode. Let’s enable it: #+BEGIN_SRC emacs-lisp - (add-hook 'Info-selection-hook 'info-colors-fontify-node) +(add-hook 'Info-selection-hook 'info-colors-fontify-node) #+END_SRC *** Prettified symbols @@ -5215,17 +5211,17 @@ prettified into simpler symbols. Here is the list of symbols that are to be prettified. You can see in the corresponding comment what symbol will be displayed. #+BEGIN_SRC emacs-lisp - (setq prettify-symbols-alist '(("lambda" . 955) ; λ - ("mapc" . 8614) ; ↦ - ("map" . 8614) ; ↦ - (">>" . 187) ; » - ("<<" . 171) ; « - )) +(setq prettify-symbols-alist '(("lambda" . 955) ; λ + ("mapc" . 8614) ; ↦ + ("map" . 8614) ; ↦ + (">>" . 187) ; » + ("<<" . 171) ; « + )) #+END_SRC Let’s enable this mode globally. #+BEGIN_SRC emacs-lisp - (global-prettify-symbols-mode 1) +(global-prettify-symbols-mode 1) #+END_SRC *** Misc @@ -5234,12 +5230,12 @@ Let’s enable this mode globally. :END: Emacs is already silent, but let’s set the bell as visible: #+BEGIN_SRC emacs-lisp - (setq visible-bell t) +(setq visible-bell t) #+END_SRC I would also like to disable the global ~hl-mode~, I find it quite annoying. #+BEGIN_SRC emacs-lisp - (global-hl-line-mode -1) +(global-hl-line-mode -1) #+END_SRC * Footnotes diff --git a/org/config/stumpwm.org b/org/config/stumpwm.org index bccce25..7c942fd 100644 --- a/org/config/stumpwm.org +++ b/org/config/stumpwm.org @@ -92,11 +92,11 @@ different locations, but I chose an Emacs-like configuration: put everything in ~~/.stumpwm.d/~. We begin by indicating quicklisp how to properly initialize: #+begin_src lisp - #-quicklisp - (let ((quicklisp-init (merge-pathnames "quicklisp/setup.lisp" - (user-homedir-pathname)))) - (when (probe-file quicklisp-init) - (load quicklisp-init))) +#-quicklisp +(let ((quicklisp-init (merge-pathnames "quicklisp/setup.lisp" + (user-homedir-pathname)))) + (when (probe-file quicklisp-init) + (load quicklisp-init))) #+end_src Then, our first StumpWM-related code is declaring we are using the @@ -104,15 +104,15 @@ Then, our first StumpWM-related code is declaring we are using the us to avoid using the prefix ~stumpwm:~ each time we are using a function or a variable from this package. #+begin_src lisp - (in-package :stumpwm) - (setf *default-package* :stumpwm) +(in-package :stumpwm) +(setf *default-package* :stumpwm) #+end_src Since I install StumpWM with my package manager (I use the AUR’s ~stumpwm-git~ package), StumpWM’s modules are installed to ~/usr/share/stupmwm/contrib/utils/~, let’s indicate that to StumpWM. #+begin_src lisp - (set-module-dir "/usr/share/stupmwm/contrib/") +(set-module-dir "/usr/share/stupmwm/contrib/") #+end_src A startup message can be used when initializing StumpWM. For now, @@ -125,8 +125,8 @@ The first thing I want to do after that is to set some decent cursor pointer as well as get a bunch of stuff started. To see what’s in the ~autostart~ script, [[file:bin.org::#Autostart-a99e99e7][see here]]. #+begin_src lisp - (run-shell-command "xsetroot -cursor_name left_ptr") - (run-shell-command "autostart") +(run-shell-command "xsetroot -cursor_name left_ptr") +(run-shell-command "autostart") #+end_src Now, we’ll load a couple of my custom files that will be described below: @@ -142,10 +142,10 @@ Now, we’ll load a couple of my custom files that will be described below: #+name: gen-load-files #+headers: :wrap src lisp #+begin_src emacs-lisp :var files=first-loaded-files - (mapconcat (lambda (file) - (format "(load \"~/.stumpwm.d/%s\")" (car file))) - files - "\n") +(mapconcat (lambda (file) + (format "(load \"~/.stumpwm.d/%s\")" (car file))) + files + "\n") #+end_src This is equivalent to the Common Lisp code: @@ -161,8 +161,8 @@ This is equivalent to the Common Lisp code: Once the modeline file is loaded, let’s indicate StumpWM to activate it: #+begin_src lisp - (when *initializing* - (mode-line)) +(when *initializing* + (mode-line)) #+end_src Another thing I want to set is how focus is linked to my mouse: only @@ -170,8 +170,8 @@ on click. I /HATE/ it when focus follows my mouse like some damn dog after its ball. Also, the meta key will be used to move floating windows. #+begin_src lisp - (setf *mouse-focus-policy* :click - ,*float-window-modifier* :META) +(setf *mouse-focus-policy* :click + ,*float-window-modifier* :META) #+end_src Next, some modules will be loaded from the ~stumpwm-contrib~ package @@ -190,10 +190,10 @@ including a short description of what they are for: #+name: gen-load-modules #+headers: :wrap src lisp #+begin_src emacs-lisp :var modules=loaded-modules - (mapconcat (lambda (module) - (format "(load-module \"%s\")" (car module))) - modules - "\n") +(mapconcat (lambda (module) + (format "(load-module \"%s\")" (car module))) + modules + "\n") #+end_src #+RESULTS[508e36f9747f1da901bbee63582416a8a6ba2c2f]: gen-load-modules @@ -208,7 +208,7 @@ including a short description of what they are for: Finally, we can notify the user everything is ready. #+begin_src lisp - (setf *startup-message* "StumpWM is ready!") +(setf *startup-message* "StumpWM is ready!") #+end_src And it’s done! We can now move on to the creation of the other CLisp files. @@ -223,42 +223,42 @@ me invoking too many Firefox instances. Either Firefox is not already running and an instance is launched, or one already is and we are brought to it. This is done like so: #+begin_src lisp - (defcommand firefox () () - "Run or raise Firefox." - (run-or-raise "firefox" '(:class "Firefox") t nil)) +(defcommand firefox () () + "Run or raise Firefox." + (run-or-raise "firefox" '(:class "Firefox") t nil)) #+end_src Next, this command will not only close the current window, but it will also close the current frame. #+begin_src lisp - (defcommand delete-window-and-frame () () - "Delete the current frame with its window." - (delete-window) - (remove-split)) +(defcommand delete-window-and-frame () () + "Delete the current frame with its window." + (delete-window) + (remove-split)) #+end_src The two following commands will create a new frame to the right and below the current frame respectively, then focus it. #+begin_src lisp - (defcommand hsplit-and-focus () () - "Create a new frame on the right and focus it." - (hsplit) - (move-focus :right)) +(defcommand hsplit-and-focus () () + "Create a new frame on the right and focus it." + (hsplit) + (move-focus :right)) - (defcommand vsplit-and-focus () () - "Create a new frame below and move focus to it." - (vsplit) - (move-focus :down)) +(defcommand vsplit-and-focus () () + "Create a new frame below and move focus to it." + (vsplit) + (move-focus :down)) #+end_src Now, let’s create a command for invoking the terminal, optionally with a program. #+begin_src lisp - (defcommand term (&optional program) () - "Invoke a terminal, possibly with a @arg{program}." - (run-shell-command (if program - (format nil "kitty ~A" program) - "kitty"))) +(defcommand term (&optional program) () + "Invoke a terminal, possibly with a @arg{program}." + (run-shell-command (if program + (format nil "kitty ~A" program) + "kitty"))) #+end_src And done! Next! @@ -297,10 +297,10 @@ code looks like so: #+name: gen-colors #+headers: :wrap src lisp #+begin_src emacs-lisp :var colors=nord-colors - (mapconcat (lambda (color) - (format "(defvar phundrak-%s \"%s\")" (car color) (cadr color))) - colors - "\n") +(mapconcat (lambda (color) + (format "(defvar phundrak-%s \"%s\")" (car color) (cadr color))) + colors + "\n") #+end_src #+RESULTS[08b3db7a2b4f31d641bcd096ff265eae06879244]: gen-colors @@ -332,45 +332,45 @@ And with that we’re done! :END: The modeline is pretty easy. First, let’s load the ~colors.lisp~ file we just created: #+begin_src lisp - (load "~/.stumpwm.d/colors.lisp") +(load "~/.stumpwm.d/colors.lisp") #+end_src Next, we can set some colors for the modeline. Let’s set the background of the modeline to Nord1 and the foreground to Nord5, I think this is a pretty good combination. #+begin_src lisp - (setf *mode-line-background-color* phundrak-nord1 - ,*mode-line-foreground-color* phundrak-nord5) +(setf *mode-line-background-color* phundrak-nord1 + ,*mode-line-foreground-color* phundrak-nord5) #+end_src We /could/ also use some borders in the modeline. But we won’t. Let’s still set its color to Nord1, just in case. #+begin_src lisp - (setf *mode-line-border-color* phundrak-nord1 - ,*mode-line-border-width* 0) +(setf *mode-line-border-color* phundrak-nord1 + ,*mode-line-border-width* 0) #+end_src The timeout of the modeline indicates how often it refreshes in seconds. I think one second is good. #+begin_src lisp - (setf *mode-line-timeout* 1) +(setf *mode-line-timeout* 1) #+end_src Next we get to the content of the modeline. This format follows the format indicated in the manpage of ~date~. #+begin_src lisp - (setf *time-modeline-string* "%F %H:%M") +(setf *time-modeline-string* "%F %H:%M") #+end_src Let’s also indicate how the groupname is displayed. #+begin_src lisp - (setf *group-format* "%t") +(setf *group-format* "%t") #+end_src The window format should display first its window number, then its titled, limited to 30 characters. #+begin_src lisp - (setf *window-format* "%n: %30t") +(setf *window-format* "%n: %30t") #+end_src Here are some modules that we will load for the modeline: @@ -384,10 +384,10 @@ Here are some modules that we will load for the modeline: #+name: gen-load-modeline-modules #+headers: :wrap src lisp #+begin_src emacs-lisp :var modules=modeline-modules - (mapconcat (lambda (module) - (format "(load-module \"%s\")" (car module))) - modules - "\n") +(mapconcat (lambda (module) + (format "(load-module \"%s\")" (car module))) + modules + "\n") #+end_src #+RESULTS[75023085d7c69ae09044826218830e6b678d5959]: gen-load-modeline-modules @@ -405,7 +405,7 @@ highlighted, and ~%u~ will display urgent windows if there are any. ~%d~ on the other hand will display the date in the format set above, while ~%B~ will display the battery level of the laptop. #+begin_src lisp - (setf *screen-mode-line-format* (list "%g %v %u ^> %C | %M | %B | %d")) +(setf *screen-mode-line-format* (list "%g %v %u ^> %C | %M | %B | %d")) #+end_src This variable as you can see is a list of elements, although here I am @@ -455,22 +455,22 @@ is the list of groups I will be using: #+name: gen-groups #+headers: :exports none #+begin_src emacs-lisp :var groups=list-groups - (let ((make-group (lambda (group &optional first-p) - (let ((group-name (car group)) - (group-type (nth 3 group))) - (format "(%s \"%s\")" - (if first-p - "grename" - (pcase group-type - ("Dynamic" "gnewbg-dynamic") - ("Floating" "gnewbg-float") - (otherwise "gnewbg"))) - group-name))))) - (string-join `(,(funcall make-group (car groups) t) - ,@(mapcar (lambda (group) - (funcall make-group group)) - (cdr groups))) - "\n")) +(let ((make-group (lambda (group &optional first-p) + (let ((group-name (car group)) + (group-type (nth 3 group))) + (format "(%s \"%s\")" + (if first-p + "grename" + (pcase group-type + ("Dynamic" "gnewbg-dynamic") + ("Floating" "gnewbg-float") + (otherwise "gnewbg"))) + group-name))))) + (string-join `(,(funcall make-group (car groups) t) + ,@(mapcar (lambda (group) + (funcall make-group group)) + (cdr groups))) + "\n")) #+end_src #+RESULTS[22540ee038b7206f965b7ca48521e93bdccb5de8]: gen-groups @@ -485,8 +485,8 @@ is the list of groups I will be using: Groups are specified this way: #+begin_src lisp - (when *initializing* - <>) +(when *initializing* + <>) #+end_src By default, if nothing is specified as per the group type, my groups @@ -496,7 +496,7 @@ also be dynamic tiling groups or floating groups. Next, let’s make sure no previous window placement rule is in place, this will avoid unexpected and hard-to-debug behavior. #+begin_src lisp - (clear-window-placement-rules) +(clear-window-placement-rules) #+end_src As you can see in the table [[list-groups]] above, I also indicated my @@ -505,27 +505,27 @@ class, so it will be pretty straightforward to the corresponding code. #+name: gen-rules #+headers: :wrap src lisp #+begin_src emacs-lisp :var rules=list-groups - (require 'seq) - (let ((output "") - (rules (seq-filter (lambda (rule) rule) - (mapcar (lambda (line) - (let ((classes (caddr line))) - (unless (string= "" classes) - (cons - (split-string classes "," t "[[:space:]]*") - (car line))))) - rules)))) - (progn - (seq-do (lambda (rule) - (let ((classes (car rule)) - (group (cdr rule))) - (dolist (class classes) - (setf output (format "%s\n%s" - `(define-frame-preference ,(format "\"%s\"" group) - (nil t t :class ,(format "\"%s\"" class))) - output))))) - rules) - output)) +(require 'seq) +(let ((output "") + (rules (seq-filter (lambda (rule) rule) + (mapcar (lambda (line) + (let ((classes (caddr line))) + (unless (string= "" classes) + (cons + (split-string classes "," t "[[:space:]]*") + (car line))))) + rules)))) + (progn + (seq-do (lambda (rule) + (let ((classes (car rule)) + (group (cdr rule))) + (dolist (class classes) + (setf output (format "%s\n%s" + `(define-frame-preference ,(format "\"%s\"" group) + (nil t t :class ,(format "\"%s\"" class))) + output))))) + rules) + output)) #+end_src This can be written this way: @@ -550,28 +550,28 @@ three terminal windows to open by default: - and two terminals This can be done like so: #+begin_src lisp - (defun my-term-init (current-group _last-group) - "Create terminals in the first group when none are already there." - (let ((term-group (select-group (current-screen) "2")) - (windows (group-windows current-group))) - (when (and (equal current-group term-group) - (null windows)) - (unless (= 1 (length (group-frames current-group))) - (only)) - (term "htop") - (term) - (term)))) +(defun my-term-init (current-group _last-group) + "Create terminals in the first group when none are already there." + (let ((term-group (select-group (current-screen) "2")) + (windows (group-windows current-group))) + (when (and (equal current-group term-group) + (null windows)) + (unless (= 1 (length (group-frames current-group))) + (only)) + (term "htop") + (term) + (term)))) #+end_src Let’s add a hook for that now: #+begin_src lisp - (add-hook *focus-group-hook* 'my-term-init) +(add-hook *focus-group-hook* 'my-term-init) #+end_src By the way, dynamic groups should have a split ratio of half of the available space. #+begin_src lisp - (setf *dynamic-group-master-split-ratio* 1/2) +(setf *dynamic-group-master-split-ratio* 1/2) #+end_src * Theme @@ -581,7 +581,7 @@ available space. :END: As in the modeline file, the first thing we’ll do is to load our colors. #+begin_src lisp - (load "~/.stumpwm.d/colors.lisp") +(load "~/.stumpwm.d/colors.lisp") #+end_src We can now go onto more serious business. @@ -599,9 +599,9 @@ There’s a quickfix available while we wait for ~clx-truetype~ to be once again available: clone it in quicklisp’s local projects. You will obviously need to have quicklisp installed (for that, follow the [[https://www.quicklisp.org/beta/#installation][official instructions]]), then execute the following shell commands: -#+begin_src sh - cd ~/quicklisp/local-projects/ - git clone https://github.com/lihebi/clx-truetype.git +#+begin_src sh :dir ~/quicklisp/local-projects +cd ~/quicklisp/local-projects/ +git clone https://github.com/lihebi/clx-truetype.git #+end_src This will make ~clx-truetype~ available to quicklisp, and you can run @@ -611,8 +611,8 @@ issue (running it again is necessary to install its dependencies). Now that this is out of the way, let’s add two lines so we can use TTF fonts: #+begin_src lisp - (ql:quickload :clx-truetype) - (load-module "ttf-fonts") +(ql:quickload :clx-truetype) +(load-module "ttf-fonts") #+end_src The documentation says we should be able to also use OTF fonts, but so far I’ve had no luck loading one. Loading more than one font to use @@ -636,18 +636,18 @@ work). #+name: gen-fonts #+headers: :wrap src lisp #+begin_src emacs-lisp :var fonts=list-fonts - (format "(set-font `(%s))" - (mapconcat (lambda (font) - (let ((family (nth 0 font)) - (subfamily (nth 1 font)) - (size (nth 2 font))) - (format ",%s" `(make-instance 'xft:font - :family ,(format "\"%s\"" family) - :subfamily ,(format "\"%s\"" subfamily) - :size ,size - :antialias t)))) - fonts - "\n ")) +(format "(set-font `(%s))" + (mapconcat (lambda (font) + (let ((family (nth 0 font)) + (subfamily (nth 1 font)) + (size (nth 2 font))) + (format ",%s" `(make-instance 'xft:font + :family ,(format "\"%s\"" family) + :subfamily ,(format "\"%s\"" subfamily) + :size ,size + :antialias t)))) + fonts + "\n ")) #+end_src The code equivalent of this table can be seen below: @@ -671,17 +671,17 @@ We can now set a couple of colors for StumpWM. Not that we will see them often since I don’t like borders on my windows, but in case I want to get them back, they’ll be nice to have. #+begin_src lisp - (set-border-color phundrak-nord1) - (set-focus-color phundrak-nord1) - (set-unfocus-color phundrak-nord3) - (set-float-focus-color phundrak-nord1) - (set-float-unfocus-color phundrak-nord3) +(set-border-color phundrak-nord1) +(set-focus-color phundrak-nord1) +(set-unfocus-color phundrak-nord3) +(set-float-focus-color phundrak-nord1) +(set-float-unfocus-color phundrak-nord3) #+end_src Let’s also set the colors of the message and input windows: #+begin_src lisp - (set-fg-color phundrak-nord4) - (set-bg-color phundrak-nord1) +(set-fg-color phundrak-nord4) +(set-bg-color phundrak-nord1) #+end_src As I said, I don’t like borders, so I’ll remove them. I’ll still keep @@ -689,11 +689,11 @@ the window’s title bar available when it’s floating, and this is also where I can set the format of its title: its number as well as its name, limited to thirty characters. #+begin_src lisp - (setf *normal-border-width* 0 - ,*float-window-border* 0 - ,*float-window-title-height* 15 - ,*window-border-style* :none - ,*window-format* "%n:%30t") +(setf *normal-border-width* 0 + ,*float-window-border* 0 + ,*float-window-title-height* 15 + ,*window-border-style* :none + ,*window-format* "%n:%30t") #+end_src ** Message and Input Windows @@ -704,10 +704,10 @@ The Input windows as well as the message windows should both be at the top of my screen. And I believe a padding of five pixels for the message windows is good. #+begin_src lisp - (setf *input-window-gravity* :top - ,*message-window-padding* 10 - ,*message-window-y-padding* 10 - ,*message-window-gravity* :top) +(setf *input-window-gravity* :top + ,*message-window-padding* 10 + ,*message-window-y-padding* 10 + ,*message-window-gravity* :top) #+end_src ** Gaps Between Frames @@ -719,21 +719,21 @@ plain ~i3~. In Awesome, I still have gaps. And in StumpWM, I shall still use gaps. In order to use them, let’s load a module dedicated to gaps in StumpWM: #+begin_src lisp - (load-module "swm-gaps") +(load-module "swm-gaps") #+end_src Now that this is done, I can now set some variables bound to this package. #+begin_src lisp - (setf swm-gaps:*head-gaps-size* 0 - swm-gaps:*inner-gaps-size* 5 - swm-gaps:*outer-gaps-size* 15) +(setf swm-gaps:*head-gaps-size* 0 + swm-gaps:*inner-gaps-size* 5 + swm-gaps:*outer-gaps-size* 15) #+end_src Finally, let’s enable our gaps: #+begin_src lisp - (when *initializing* - (swm-gaps:toggle-gaps)) +(when *initializing* + (swm-gaps:toggle-gaps)) #+end_src * Keybinds @@ -745,7 +745,7 @@ Buckle up, this chapter is going to be *long*, because me loves LOTS of keybinds First, let’s declare again we are using the default package ~stumpwm~: #+begin_src lisp - (in-package :stumpwm) +(in-package :stumpwm) #+end_src This will avoid us always repeating ~stumpwm:define-key~ or ~stumpwm:kbd~ @@ -785,12 +785,12 @@ it with ~set-prefix-key~. I personally like to have my space key as a leader key, but in order to not have it conflict with Emacs, I also need to press the super key too. #+begin_src lisp - (set-prefix-key (kbd "s-SPC")) +(set-prefix-key (kbd "s-SPC")) #+end_src Also, let’s enable ~which-key~: #+begin_src lisp - (which-key-mode) +(which-key-mode) #+end_src Lastly, before we get more into details, keep in mind that I use the @@ -843,10 +843,10 @@ First, let’s create my ~rofi~ scripts keymap. Here’s the equivalent in Common Lisp. #+begin_src lisp - (defvar *my-rofi-keymap* - (let ((m (make-sparse-keymap))) - <> - m)) +(defvar *my-rofi-keymap* + (let ((m (make-sparse-keymap))) + <> + m)) #+end_src Let’s also create a keymap for screenshots. @@ -861,10 +861,10 @@ Let’s also create a keymap for screenshots. Here’s the equivalent in Common Lisp. #+begin_src lisp - (defvar *my-screenshot-keymap* - (let ((m (make-sparse-keymap))) - <> - m)) +(defvar *my-screenshot-keymap* + (let ((m (make-sparse-keymap))) + <> + m)) #+end_src We can now define our applications keymap which will reference both @@ -883,22 +883,22 @@ the above keymaps. This translates to: #+begin_src lisp - (defvar *my-applications-keymap* - (let ((m (make-sparse-keymap))) - <> - m)) +(defvar *my-applications-keymap* + (let ((m (make-sparse-keymap))) + <> + m)) #+end_src The application keymap can now be bound to the root map like so: #+begin_src lisp - (define-key *root-map* (kbd "a") '*my-applications-keymap*) +(define-key *root-map* (kbd "a") '*my-applications-keymap*) #+end_src I will also bind to the top map ~s-RET~ in order to open a new terminal window. The screenshot keymap is also bound to the ScreenPrint key. #+begin_src lisp - (define-key *top-map* (kbd "s-RET") "term") - (define-key *top-map* (kbd "Print") '*my-screenshot-keymap*) +(define-key *top-map* (kbd "s-RET") "term") +(define-key *top-map* (kbd "Print") '*my-screenshot-keymap*) #+end_src ** End of Session, Powering Off, and the Likes @@ -922,15 +922,15 @@ whishes to do. This translates to: #+begin_src lisp - (defvar *my-end-session-keymap* - (let ((m (make-sparse-keymap))) - <> - m)) +(defvar *my-end-session-keymap* + (let ((m (make-sparse-keymap))) + <> + m)) #+end_src Which is bound in the root map to ~q~: #+begin_src lisp - (define-key *root-map* (kbd "q") '*my-end-session-keymap*) +(define-key *root-map* (kbd "q") '*my-end-session-keymap*) #+end_src ** Groups @@ -945,21 +945,18 @@ this: #+name: group-keybind-gen #+header: :noweb no :results verbatim :exports none :var convert="no" #+begin_src emacs-lisp :var groups=list-groups mod="s" action="gselect" map="*top-map*" convert="yes" - (mapconcat (lambda (group) - (let ((group-nbr (nth 1 group))) - (format "%S" `(define-key - ,(make-symbol map) - ;; (kbd ,(if (string= convert "yes") - ;; (format "%s-<>" mod group-nbr) - ;; (number-to-string group-nbr))) - (kbd ,(format "%s-%s" - mod - (if (string= "yes" convert) - (format "<>" group-nbr) - (number-to-string group-nbr)))) - ,(format "%s %d" action group-nbr))))) - groups - "\n") +(mapconcat (lambda (group) + (let ((group-nbr (nth 1 group))) + (format "%S" `(define-key + ,(make-symbol map) + (kbd ,(format "%s-%s" + mod + (if (string= "yes" convert) + (format "<>" group-nbr) + (number-to-string group-nbr)))) + ,(format "%s %d" action group-nbr))))) + groups + "\n") #+end_src #+RESULTS[09b139b0e127a88b3e4e2a05a609ccfcb7825b3c]: group-keybind-gen @@ -974,7 +971,7 @@ this: #+header: :cache yes :noweb yes :wrap src lisp #+begin_src emacs-lisp - <> +<> #+end_src #+RESULTS[627ef5c7e456944dd624c322529699e11f2a041b]: @@ -995,7 +992,7 @@ of the group/. As mentioned before, due to my keyboard layout Shift + /number/ is actually just /number/ for me (e.g. Shift + ~"~ results in ~1~), so there’s no need to convert the group number to another character. #+begin_src emacs-lisp :wrap src lisp - <> +<> #+end_src #+RESULTS[6577510905e5cce124ff563a6d68a7f64fc8683c]: @@ -1012,7 +1009,7 @@ so there’s no need to convert the group number to another character. If I want to send a window to another group without following it, I’ll use ~s-S-C-~, which gives us the following: #+begin_src emacs-lisp :wrap src lisp - <> +<> #+end_src #+RESULTS[55852a5a035c23f078ba0a97120151c059fa955f]: @@ -1029,7 +1026,7 @@ use ~s-S-C-~, which gives us the following: And if I want to bring the windows of another group into the current group, I’ll use ~s-C-~: #+begin_src emacs-lisp :wrap src lisp :exports results - <> +<> #+end_src #+RESULTS[b536bb0359e6e9e10e98635c82bed3d348d75ac5]: @@ -1048,19 +1045,19 @@ StumpWM also has already a nice keymap for managing groups called already bound, but since I plan on erasing ~*root-map*~ in the near future before binding stuff to it, I prefer to bind it already) #+begin_src lisp - (define-key *root-map* (kbd "g") '*groups-map*) +(define-key *root-map* (kbd "g") '*groups-map*) #+end_src And a binding to ~vgroups~ is done on ~*groups-map*~ in order to regroup similar keybinds. #+begin_src lisp - (define-key *groups-map* (kbd "G") "vgroups") +(define-key *groups-map* (kbd "G") "vgroups") #+end_src I grew accustomed to ~s-ESC~ bringing me to the previous group when using AwesomeWM, so let’s define that: #+begin_src lisp - (define-key *top-map* (kbd "s-ESC") "gother") +(define-key *top-map* (kbd "s-ESC") "gother") #+end_src ** Frames and Windows management @@ -1125,20 +1122,20 @@ ourselves in ~*my-frames-management-keymap*~, pressing ~F~ will bring us in ~*my-frames-float-keymap*~. #+begin_src lisp - (defvar *my-frames-float-keymap* - (let ((m (make-sparse-keymap))) - <> - m)) +(defvar *my-frames-float-keymap* + (let ((m (make-sparse-keymap))) + <> + m)) - (defvar *my-frames-management-keymap* - (let ((m (make-sparse-keymap))) - <> - m)) +(defvar *my-frames-management-keymap* + (let ((m (make-sparse-keymap))) + <> + m)) #+end_src Let’s bind ~*my-frames-management-keymap*~ in ~*root-keymap*~: #+begin_src lisp - (define-key *root-map* (kbd "w") '*my-frames-management-keymap*) +(define-key *root-map* (kbd "w") '*my-frames-management-keymap*) #+end_src That way, if we want for instance to split our current frame @@ -1163,7 +1160,7 @@ I also bound a couple of these functions to the top keymap for easier access: This translates to: #+begin_src lisp - <> +<> #+end_src Being a [[https://bepo.fr/wiki/Accueil][bépo layout]] user, the ~hjkl~ keys don’t exactly fit me, as you @@ -1171,19 +1168,19 @@ might have noticed with my use of ~ctsr~ which is its equivalent. Due to this, the interactive keymap for ~iresize~ is not ideal for me, let me redefine it: #+begin_src lisp - (define-interactive-keymap (iresize tile-group) (:on-enter #'setup-iresize - :on-exit #'resize-unhide - :abort-if #'abort-resize-p) - ((kbd "c") "resize-direction left") - ((kbd "t") "resize-direction down") - ((kbd "s") "resize-direction up") - ((kbd "r") "resize-direction right")) +(define-interactive-keymap (iresize tile-group) (:on-enter #'setup-iresize + :on-exit #'resize-unhide + :abort-if #'abort-resize-p) + ((kbd "c") "resize-direction left") + ((kbd "t") "resize-direction down") + ((kbd "s") "resize-direction up") + ((kbd "r") "resize-direction right")) #+end_src As with groups management, I grew used to ~s-TAB~ in AwesomeWM bringing me back to the previously focused window. #+begin_src lisp - (define-key *top-map* (kbd "s-TAB") "other-window") +(define-key *top-map* (kbd "s-TAB") "other-window") #+end_src ** Windows management @@ -1206,12 +1203,12 @@ with Emacs’ buffers. | ~p~ | ~prev~ | #+begin_src lisp - (defvar *my-buffers-management-keymap* - (let ((m (make-sparse-keymap))) - <> - m)) +(defvar *my-buffers-management-keymap* + (let ((m (make-sparse-keymap))) + <> + m)) - (define-key *root-map* (kbd "b") '*my-buffers-management-keymap*) +(define-key *root-map* (kbd "b") '*my-buffers-management-keymap*) #+end_src ** Media and Media Control @@ -1236,7 +1233,7 @@ of MPD. Cela donne le code suivant: #+begin_src lisp - <> +<> #+end_src Another one will be defined for the general audio of my computer. And @@ -1253,7 +1250,7 @@ for my screen’s backlight. | ~m~ | ~exec amixer -q set Master 1+ toggle~ | #+begin_src lisp - <> +<> #+end_src Then, let’s declare a keymap for our media controls. @@ -1272,12 +1269,12 @@ Then, let’s declare a keymap for our media controls. Let’s translate this table in CommonLisp: #+begin_src lisp - (defvar *my-media-keymap* - (let ((m (make-sparse-keymap))) - <> - m)) +(defvar *my-media-keymap* + (let ((m (make-sparse-keymap))) + <> + m)) - (define-key *root-map* (kbd "m") '*my-media-keymap*) +(define-key *root-map* (kbd "m") '*my-media-keymap*) #+end_src I will also define on ~*top-map*~ some basic volume management keybinds @@ -1298,7 +1295,7 @@ media-related, but I’ll add keybinds for my screen’s backlight. | ~XF86MonBrightnessUp~ | ~exec xbacklight -inc 2~ | #+begin_src lisp - <> +<> #+end_src ** Misc @@ -1316,7 +1313,7 @@ anywhere else: | ~r~ | ~reload~ | #+begin_src lisp - <> +<> #+end_src From time to time, I need to switch between different keyboard @@ -1330,12 +1327,12 @@ games and the bépo layout most of the time. I’ll use the command | ~u~ | ~exec setxkbmap us~ | #+begin_src lisp - (defvar *my-keyboard-layout-keymap* - (let ((m (make-sparse-keymap))) - <> - m)) +(defvar *my-keyboard-layout-keymap* + (let ((m (make-sparse-keymap))) + <> + m)) - (define-key *root-map* (kbd "k") '*my-keyboard-layout-keymap*) +(define-key *root-map* (kbd "k") '*my-keyboard-layout-keymap*) #+end_src * org functions :noexport: @@ -1345,54 +1342,54 @@ games and the bépo layout most of the time. I’ll use the command #+name: keybinds-gen #+begin_src emacs-lisp :var map="m" keybinds=frames-float - (mapconcat (lambda (keybind) - (format "%s" (let ((key (let ((s (car keybind))) - (substring-no-properties s 1 (1- (length s))))) - (function (let ((s (cadr keybind))) - (substring-no-properties s 1 (1- (length s)))))) - `(define-key ,map - (kbd ,(format "\"%s\"" key)) - ,(if (string-prefix-p "'" function t) - function - (format "\"%s\"" function)))))) - keybinds - "\n") +(mapconcat (lambda (keybind) + (format "%s" (let ((key (let ((s (car keybind))) + (substring-no-properties s 1 (1- (length s))))) + (function (let ((s (cadr keybind))) + (substring-no-properties s 1 (1- (length s)))))) + `(define-key ,map + (kbd ,(format "\"%s\"" key)) + ,(if (string-prefix-p "'" function t) + function + (format "\"%s\"" function)))))) + keybinds + "\n") #+end_src #+name: interactive-gen #+begin_src emacs-lisp :var name="inter" keys=inter-mpc - (format "%s" - `(define-interactive-keymap ,name () - "\n " - ,(mapconcat (lambda (keybind) - (format "%s" - (let ((key (let ((s (car keybind))) - (substring-no-properties s - 1 - (1- (length s))))) - (command (let ((s (cadr keybind))) - (substring-no-properties s - 1 - (1- (length s)))))) - `((kbd ,(format "\"%s\"" key)) - ,(format "\"%s\"" command))))) - keys - "\n "))) +(format "%s" + `(define-interactive-keymap ,name () + "\n " + ,(mapconcat (lambda (keybind) + (format "%s" + (let ((key (let ((s (car keybind))) + (substring-no-properties s + 1 + (1- (length s))))) + (command (let ((s (cadr keybind))) + (substring-no-properties s + 1 + (1- (length s)))))) + `((kbd ,(format "\"%s\"" key)) + ,(format "\"%s\"" command))))) + keys + "\n "))) #+end_src #+name: num-to-char #+begin_src emacs-lisp :var table=number-to-char-table num=0 - (let ((char (replace-regexp-in-string (regexp-quote "~") - "" - (let* ((row (assoc num table)) - (char (cadr row)) - (lispchar (caddr row))) - (if (string= "" lispchar) - char - lispchar))))) - (if (string= char "\"") - "\\\"" - char)) +(let ((char (replace-regexp-in-string (regexp-quote "~") + "" + (let* ((row (assoc num table)) + (char (cadr row)) + (lispchar (caddr row))) + (if (string= "" lispchar) + char + lispchar))))) + (if (string= char "\"") + "\\\"" + char)) #+end_src #+RESULTS[6934c27c10c3f968f70b0112d4639298e519fe61]: num-to-char diff --git a/org/config/tmux.org b/org/config/tmux.org index 6df1de0..3069325 100644 --- a/org/config/tmux.org +++ b/org/config/tmux.org @@ -24,12 +24,14 @@ Whether if a new *window* will retain the current path. Possible values are: #+BEGIN_SRC conf-unix tmux_conf_new_window_retain_current_path=true #+END_SRC + Whether if a new *pane* should retain the current path. Possible values are: - ~true~ (default) - ~false~ #+BEGIN_SRC conf-unix tmux_conf_new_window_retain_current_path=true #+END_SRC + Whether or not tmux should attempt to reconnect to the current ssh session. This is still experimental. Possible values are: - ~true~ @@ -37,6 +39,7 @@ is still experimental. Possible values are: #+BEGIN_SRC conf-unix tmux_conf_new_pane_reconnect_ssh=true #+END_SRC + Whether tmux should prompt for new session name when creating a new one. Possible values are: - ~true~ @@ -56,18 +59,21 @@ Possible values are: #+BEGIN_SRC conf-unix tmux_conf_theme_24b_colour=false #+END_SRC + These variables are for chosing the window style. I use the default one. #+BEGIN_SRC conf-unix - tmux_conf_theme_window_fg='default' - tmux_conf_theme_window_bg='default' +tmux_conf_theme_window_fg='default' +tmux_conf_theme_window_bg='default' #+END_SRC + Whether the focused pane should be highlighted (only available in tmux >= 2.1). Possible values are: - ~true~ - ~false~ (default) #+BEGIN_SRC conf-unix - tmux_conf_theme_highlight_focused_pane=false +tmux_conf_theme_highlight_focused_pane=false #+END_SRC + Set the terminal title. Built-in variables are: - =#{circled_window_index}= - =#{circled_session_name}= @@ -76,16 +82,17 @@ Set the terminal title. Built-in variables are: - =#{username}= - =#{username_ssh}= #+BEGIN_SRC conf-unix - tmux_conf_theme_terminal_title='#h ❐ #S ● #I #W' +tmux_conf_theme_terminal_title='#h ❐ #S ● #I #W' #+END_SRC + These variables set the left/right separators between sections. With the current values, you don’t need to install Powerline, but only fonts patched with Powerline symbols or the standalone PowerlineSymbols.otf font. #+BEGIN_SRC conf-unix - tmux_conf_theme_left_separator_main='\uE0B0' - tmux_conf_theme_left_separator_sub='\uE0B1' - tmux_conf_theme_right_separator_main='\uE0B2' - tmux_conf_theme_right_separator_sub='\uE0B3' +tmux_conf_theme_left_separator_main='\uE0B0' +tmux_conf_theme_left_separator_sub='\uE0B1' +tmux_conf_theme_right_separator_main='\uE0B2' +tmux_conf_theme_right_separator_sub='\uE0B3' #+END_SRC ** Colors and style @@ -103,45 +110,52 @@ Choose the style of the pane borders. Possible values are: #+BEGIN_SRC conf-unix tmux_conf_theme_pane_border_style=thin #+END_SRC + Declare what the colors of the focused pane should be. The first variable specifies the foreground color, the other the background color. #+BEGIN_SRC conf-unix - tmux_conf_theme_focused_pane_fg='default' - tmux_conf_theme_focused_pane_bg='#0087d7' +tmux_conf_theme_focused_pane_fg='default' +tmux_conf_theme_focused_pane_bg='#0087d7' #+END_SRC + Here you can set the colors of the pane borders. #+BEGIN_SRC conf-unix - tmux_conf_theme_pane_border='#444444' - tmux_conf_theme_pane_active_border='#00afff' +tmux_conf_theme_pane_border='#444444' +tmux_conf_theme_pane_active_border='#00afff' #+END_SRC + With these variables, you can set the colors for the pane indicators. #+BEGIN_SRC conf-unix - tmux_conf_theme_pane_indicator='#00afff' - tmux_conf_theme_pane_active_indicator='#00afff' +tmux_conf_theme_pane_indicator='#00afff' +tmux_conf_theme_pane_active_indicator='#00afff' #+END_SRC + These variables set the colors and the style of the status line. #+BEGIN_SRC conf-unix - tmux_conf_theme_message_fg='#000000' - tmux_conf_theme_message_bg='#ffff00' - tmux_conf_theme_message_attr='bold' +tmux_conf_theme_message_fg='#000000' +tmux_conf_theme_message_bg='#ffff00' +tmux_conf_theme_message_attr='bold' #+END_SRC + Same as above for the status line command style. #+BEGIN_SRC conf-unix - tmux_conf_theme_message_command_fg='#ffff00' - tmux_conf_theme_message_command_bg='#000000' - tmux_conf_theme_message_command_attr='bold' +tmux_conf_theme_message_command_fg='#ffff00' +tmux_conf_theme_message_command_bg='#000000' +tmux_conf_theme_message_command_attr='bold' #+END_SRC + These variables set the style of the window modes. #+BEGIN_SRC conf-unix - tmux_conf_theme_mode_fg='#000000' - tmux_conf_theme_mode_bg='#ffff00' - tmux_conf_theme_mode_attr='bold' +tmux_conf_theme_mode_fg='#000000' +tmux_conf_theme_mode_bg='#ffff00' +tmux_conf_theme_mode_attr='bold' #+END_SRC + Set the style of the status line. #+BEGIN_SRC conf-unix - tmux_conf_theme_status_fg='#8a8a8a' - tmux_conf_theme_status_bg='#080808' - tmux_conf_theme_status_attr='none' +tmux_conf_theme_status_fg='#8a8a8a' +tmux_conf_theme_status_bg='#080808' +tmux_conf_theme_status_attr='none' #+END_SRC ** Window status bar @@ -152,10 +166,11 @@ The following variables are to set the window’s status style and format. Sets the colors and style of the window status. #+BEGIN_SRC conf-unix - tmux_conf_theme_window_status_fg='#8a8a8a' - tmux_conf_theme_window_status_bg='#080808' - tmux_conf_theme_window_status_attr='none' +tmux_conf_theme_window_status_fg='#8a8a8a' +tmux_conf_theme_window_status_bg='#080808' +tmux_conf_theme_window_status_attr='none' #+END_SRC + Sets the format of the window status. Built-in variables are: - =#{circled_window_index}= - =#{circled_session_name}= @@ -166,12 +181,14 @@ Sets the format of the window status. Built-in variables are: #+BEGIN_SRC conf-unix tmux_conf_theme_window_status_format='#I #W' #+END_SRC + Sets the colors and style of the current window status. #+BEGIN_SRC conf-unix - tmux_conf_theme_window_status_current_fg='#000000' - tmux_conf_theme_window_status_current_bg='#00afff' - tmux_conf_theme_window_status_current_attr='bold' +tmux_conf_theme_window_status_current_fg='#000000' +tmux_conf_theme_window_status_current_bg='#00afff' +tmux_conf_theme_window_status_current_attr='bold' #+END_SRC + Sets the format of the currentwindow status. Built-in variables are: - =#{circled_window_index}= - =#{circled_session_name}= @@ -180,26 +197,30 @@ Sets the format of the currentwindow status. Built-in variables are: - =#{username}= - =#{username_ssh}= #+BEGIN_SRC conf-unix - tmux_conf_theme_window_status_current_format='#I #W' +tmux_conf_theme_window_status_current_format='#I #W' #+END_SRC Sets the window activity status style. + #+BEGIN_SRC conf-unix - tmux_conf_theme_window_status_activity_fg='default' - tmux_conf_theme_window_status_activity_bg='default' - tmux_conf_theme_window_status_activity_attr='underscore' +tmux_conf_theme_window_status_activity_fg='default' +tmux_conf_theme_window_status_activity_bg='default' +tmux_conf_theme_window_status_activity_attr='underscore' #+END_SRC + Sets the window bell status style. #+BEGIN_SRC conf-unix - tmux_conf_theme_window_status_bell_fg='#ffff00' - tmux_conf_theme_window_status_bell_bg='default' - tmux_conf_theme_window_status_bell_attr='blink,bold' +tmux_conf_theme_window_status_bell_fg='#ffff00' +tmux_conf_theme_window_status_bell_bg='default' +tmux_conf_theme_window_status_bell_attr='blink,bold' #+END_SRC + Sets the window last status style. #+BEGIN_SRC conf-unix - tmux_conf_theme_window_status_last_fg='#00afff' - tmux_conf_theme_window_status_last_bg='default' - tmux_conf_theme_window_status_last_attr='none' +tmux_conf_theme_window_status_last_fg='#00afff' +tmux_conf_theme_window_status_last_bg='default' +tmux_conf_theme_window_status_last_attr='none' #+END_SRC + Sets the left and right content of the status bar of tmux. Sections should be separated with =|=, subsections with =,=. The built-in values are: - =#{battery_bar}= @@ -223,100 +244,112 @@ separated with =|=, subsections with =,=. The built-in values are: - =#{username}= - =#{username_ssh}= #+BEGIN_SRC conf-unix - tmux_conf_theme_status_left=' ❐ #S | ↑#{?uptime_y, #{uptime_y}y,}#{?uptime_d, #{uptime_d}d,}#{?uptime_h, #{uptime_h}h,}#{?uptime_m, #{uptime_m}m,} ' - tmux_conf_theme_status_right='#{prefix}#{pairing}#{synchronized} #{?battery_status, #{battery_status},}#{?battery_bar, #{battery_bar},}#{?battery_percentage, #{battery_percentage},} , %R , %d %b | #{username}#{root} | #{hostname} ' +tmux_conf_theme_status_left=' ❐ #S | ↑#{?uptime_y, #{uptime_y}y,}#{?uptime_d, #{uptime_d}d,}#{?uptime_h, #{uptime_h}h,}#{?uptime_m, #{uptime_m}m,} ' +tmux_conf_theme_status_right='#{prefix}#{pairing}#{synchronized} #{?battery_status, #{battery_status},}#{?battery_bar, #{battery_bar},}#{?battery_percentage, #{battery_percentage},} , %R , %d %b | #{username}#{root} | #{hostname} ' #+END_SRC + Sets the left status style and colors. #+BEGIN_SRC conf-unix - tmux_conf_theme_status_left_fg='#000000,#e4e4e4,#e4e4e4' - tmux_conf_theme_status_left_bg='#ffff00,#ff00af,#00afff' - tmux_conf_theme_status_left_attr='bold,none,none' +tmux_conf_theme_status_left_fg='#000000,#e4e4e4,#e4e4e4' +tmux_conf_theme_status_left_bg='#ffff00,#ff00af,#00afff' +tmux_conf_theme_status_left_attr='bold,none,none' #+END_SRC + Sets the right status style and colors. #+BEGIN_SRC conf-unix - tmux_conf_theme_status_right_fg='#8a8a8a,#e4e4e4,#000000' - tmux_conf_theme_status_right_bg='#080808,#d70000,#e4e4e4' - tmux_conf_theme_status_right_attr='none,none,bold' +tmux_conf_theme_status_right_fg='#8a8a8a,#e4e4e4,#000000' +tmux_conf_theme_status_right_bg='#080808,#d70000,#e4e4e4' +tmux_conf_theme_status_right_attr='none,none,bold' #+END_SRC + Set the pairing indicator, its style and its attribute. #+BEGIN_SRC conf-unix - tmux_conf_theme_pairing='👓 ' # U+1F453 - tmux_conf_theme_pairing_fg='none' - tmux_conf_theme_pairing_bg='none' - tmux_conf_theme_pairing_attr='none' +tmux_conf_theme_pairing='👓 ' # U+1F453 +tmux_conf_theme_pairing_fg='none' +tmux_conf_theme_pairing_bg='none' +tmux_conf_theme_pairing_attr='none' #+END_SRC + Set the pairing indicator, its style and its attribute. #+BEGIN_SRC conf-unix - # prefix indicator - tmux_conf_theme_prefix='⌨ ' # U+2328 - tmux_conf_theme_prefix_fg='none' - tmux_conf_theme_prefix_bg='none' - tmux_conf_theme_prefix_attr='none' +tmux_conf_theme_prefix='⌨ ' # U+2328 +tmux_conf_theme_prefix_fg='none' +tmux_conf_theme_prefix_bg='none' +tmux_conf_theme_prefix_attr='none' #+END_SRC + Set the root indicator, its style and its attribute. #+BEGIN_SRC conf-unix - tmux_conf_theme_root='!' - tmux_conf_theme_root_fg='none' - tmux_conf_theme_root_bg='none' - tmux_conf_theme_root_attr='bold,blink' +tmux_conf_theme_root='!' +tmux_conf_theme_root_fg='none' +tmux_conf_theme_root_bg='none' +tmux_conf_theme_root_attr='bold,blink' #+END_SRC + Set the synchronized indicator, its style and its attribute. #+BEGIN_SRC conf-unix - tmux_conf_theme_synchronized='🔒' # U+1F512 - tmux_conf_theme_synchronized_fg='none' - tmux_conf_theme_synchronized_bg='none' - tmux_conf_theme_synchronized_attr='none' +tmux_conf_theme_synchronized='🔒' # U+1F512 +tmux_conf_theme_synchronized_fg='none' +tmux_conf_theme_synchronized_bg='none' +tmux_conf_theme_synchronized_attr='none' #+END_SRC + Set the battery bar symbols. #+BEGIN_SRC conf-unix - tmux_conf_battery_bar_symbol_full='◼' - tmux_conf_battery_bar_symbol_empty='◻' +tmux_conf_battery_bar_symbol_full='◼' +tmux_conf_battery_bar_symbol_empty='◻' #+END_SRC + Set the battery bar length in terms of amount of symbols. Possible values are: - =auto= - an integer number, e.g. 5 #+BEGIN_SRC conf-unix - tmux_conf_battery_bar_length='auto' +tmux_conf_battery_bar_length='auto' #+END_SRC + Set the battery bar palette. Possible values are: - =gradient= (default) - =heat= - =color_full_fg,color_empty_fg,color_bg= with each being an hexadecimal RGB value preceded by a pound symbol =#=. #+BEGIN_SRC conf-unix - tmux_conf_battery_bar_palette='gradient' - #tmux_conf_battery_bar_palette='#d70000,#e4e4e4,#000000' +tmux_conf_battery_bar_palette='gradient' +#tmux_conf_battery_bar_palette='#d70000,#e4e4e4,#000000' #+END_SRC + Set the hbar palette. Possible values are: - =gradient= (default) - =heat= - =color_full_fg,color_empty_fg,color_bg= with each being an hexadecimal RGB value preceded by a pound symbol =#=. #+BEGIN_SRC conf-unix - tmux_conf_battery_hbar_palette='gradient' +tmux_conf_battery_hbar_palette='gradient' #+END_SRC + Set the vbar palette. Possible values are: - =gradient= (default) - =heat= - =color_full_fg,color_empty_fg,color_bg= with each being an hexadecimal RGB value preceded by a pound symbol =#=. #+BEGIN_SRC conf-unix - tmux_conf_battery_vbar_palette='gradient' +tmux_conf_battery_vbar_palette='gradient' #+END_SRC Set symbols used to indicate whether the battery is charging or discharging. + #+BEGIN_SRC conf-unix - tmux_conf_battery_status_charging='⚡ ' # U+26A1 - tmux_conf_battery_status_discharging='🔋 ' # U+1F50B - # tmux_conf_battery_status_charging='↑' # U+2191 - # tmux_conf_battery_status_discharging='↓' # U+2193 - #tmux_conf_battery_status_charging='🔌 ' # U+1F50C +tmux_conf_battery_status_charging='⚡ ' # U+26A1 +tmux_conf_battery_status_discharging='🔋 ' # U+1F50B +# tmux_conf_battery_status_charging='↑' # U+2191 +# tmux_conf_battery_status_discharging='↓' # U+2193 +#tmux_conf_battery_status_charging='🔌 ' # U+1F50C #+END_SRC + Set the clock style. If it is displayed on the right side of the status bar, it might be better to use =%I:%M %p= rather than =%R= in =tmux_conf_theme_status_right=. #+BEGIN_SRC conf-unix - tmux_conf_theme_clock_colour='#00afff' - tmux_conf_theme_clock_style='24' +tmux_conf_theme_clock_colour='#00afff' +tmux_conf_theme_clock_style='24' #+END_SRC * Clipboard @@ -328,7 +361,7 @@ Possible values are: - ~true~ - ~false~ (default) #+BEGIN_SRC conf-unix - tmux_conf_copy_to_os_clipboard=false +tmux_conf_copy_to_os_clipboard=false #+END_SRC * User customizations @@ -338,29 +371,33 @@ Possible values are: Here we can override or undo some setting from settings from tmux. First, we can increase the history size. #+BEGIN_SRC conf-unix - set -g history-limit 10000 +set -g history-limit 10000 #+END_SRC + We can also start with mouse mode enabled. But I don’t. #+BEGIN_SRC conf-unix - #set -g mouse on +#set -g mouse on #+END_SRC + Whether or not Vi mode should be enabled. But really, we should rather export the =VISUAL= or =EDITOR= environment variables, see the tmux manual. Although I don’t, as said in my dotfish, I prefer to use Emacs. #+BEGIN_SRC conf-unix - #set -g status-keys vi - #set -g mode-keys vi +#set -g status-keys vi +#set -g mode-keys vi #+END_SRC + Replace =C-b= by =C-a= instead of using both prefixes. I personally prefer to just use =C-b=, hence why the lines are commented. #+BEGIN_SRC conf-unix - # set -gu prefix2 - # unbind C-a - # unbind C-b - # set -g prefix C-a - # bind C-a send-prefix +# set -gu prefix2 +# unbind C-a +# unbind C-b +# set -g prefix C-a +# bind C-a send-prefix #+END_SRC + Move the status line to the top. #+BEGIN_SRC conf-unix - #set -g status-position top +#set -g status-position top #+END_SRC