Compare commits
5
Commits
3a273d1ee8
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ab56f53795
|
||
|
|
7e60dbd8c3
|
||
|
|
e7a2e5ef58
|
||
|
|
234cff1006
|
||
|
|
5caf6fb658
|
@@ -1,130 +1,174 @@
|
|||||||
# ==== State ====
|
system 'bash ~/main/ocaml/epq/scripts/startup.sh >/dev/null 2>&1 &'
|
||||||
|
|
||||||
MAX_PROJECTS = 9
|
MAX_PROJECTS = 3
|
||||||
SUBS = 2 # workspaces per project
|
|
||||||
|
|
||||||
$current_project = 1 # 1..MAX_PROJECTS
|
|
||||||
$current_sub = 0 # 0..SUBS-1
|
|
||||||
|
|
||||||
# For each special workspace, remembers which workspace you were on
|
|
||||||
# before you jumped into it -- so hitting the mode key again toggles back.
|
|
||||||
$special_origin = {}
|
|
||||||
|
|
||||||
SPECIAL = {
|
SPECIAL = {
|
||||||
terminal: { cmd: "kitty" },
|
term1: { cmd: 'kitty' },
|
||||||
browser: { cmd: "firefox" },
|
term2: { cmd: 'kitty' },
|
||||||
music: { cmd: "spotify" },
|
browser: { cmd: 'firefox' },
|
||||||
misc: { cmd: nil }, # doesn't start anything
|
misc: { cmd: nil }
|
||||||
todo: { cmd: nil }, # doesn't start anything
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# ==== Helpers ====
|
$current = 0
|
||||||
|
|
||||||
def project_ws(n, sub)
|
$p_sub = Array.new(9, 0)
|
||||||
:"p#{n}_#{sub}"
|
|
||||||
|
def project_ws(n)
|
||||||
|
:"p#{n}_#{$p_sub[$current]}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def running?(process)
|
def go_project(n)
|
||||||
system("pgrep -x #{process} > /dev/null 2>&1")
|
$current = n
|
||||||
end
|
jump_ws project_ws($current)
|
||||||
|
|
||||||
def go_project(n, sub)
|
|
||||||
$current_project = n
|
|
||||||
$current_sub = sub
|
|
||||||
jump_ws project_ws(n, sub)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def in_project?(ws)
|
def in_project?(ws)
|
||||||
!SPECIAL.key?(ws)
|
!SPECIAL.key?(ws)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Toggle between a special-mode workspace (terminal/browser/music/misc/todo)
|
|
||||||
# and whatever workspace you were last on. Starts the associated app if
|
|
||||||
# it isn't already running. `ws` is the current workspace, passed in by
|
|
||||||
# the bind block (bind gives us (window, current_ws)).
|
|
||||||
def go_special(name, ws)
|
def go_special(name, ws)
|
||||||
cfg = SPECIAL.fetch(name)
|
cfg = SPECIAL.fetch(name)
|
||||||
|
|
||||||
if ws == name
|
if ws == name
|
||||||
target = $special_origin[name] || project_ws($current_project, $current_sub)
|
target = project_ws($current)
|
||||||
jump_ws target
|
jump_ws target
|
||||||
else
|
else
|
||||||
$special_origin[name] = ws
|
|
||||||
jump_ws name
|
jump_ws name
|
||||||
system("#{cfg[:cmd]} >/dev/null 2>&1 &") if cfg[:cmd] && !running?(cfg[:cmd])
|
system("#{cfg[:cmd]} >/dev/null 2>&1 &") if cfg[:cmd] && ws_empty?(name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# ==== Untouched bindings ====
|
bind 'q' do |x|
|
||||||
|
|
||||||
bind ?q do |x|
|
|
||||||
kill x
|
kill x
|
||||||
end
|
end
|
||||||
|
|
||||||
bind ?w do
|
bind 'w' do
|
||||||
system "kitty >/dev/null 2>&1 &"
|
system 'kitty >/dev/null 2>&1 &'
|
||||||
end
|
end
|
||||||
|
|
||||||
bind ?e do
|
bind 'e' do
|
||||||
exit
|
system 'bash ~/main/ocaml/epq/scripts/power.sh >/dev/null 2>&1 &'
|
||||||
end
|
end
|
||||||
|
|
||||||
bind ?f do |x|
|
bind 'd' do
|
||||||
|
system 'bash ~/main/ocaml/epq/scripts/run.sh >/dev/null 2>&1 &'
|
||||||
|
end
|
||||||
|
|
||||||
|
bind 'v' do
|
||||||
|
system 'CM_LAUNCHER=rofi clipmenu >/dev/null 2>&1 &'
|
||||||
|
end
|
||||||
|
|
||||||
|
bind 'a' do
|
||||||
|
system 'bash', '-c', "
|
||||||
|
maim -c 0.3,0.5,1.0,0.8 -s | tee /tmp/screenshot_temp.png | xclip -selection clipboard -t image/png;
|
||||||
|
if [ -s '/tmp/screenshot_temp.png' ]; then
|
||||||
|
mv /tmp/screenshot_temp.png ~/screenshots/$(date +%Y-%m-%d_%H:%M:%S).png;
|
||||||
|
fi
|
||||||
|
"
|
||||||
|
end
|
||||||
|
|
||||||
|
bind 123, :none do
|
||||||
|
system 'bash', '-c', %q(
|
||||||
|
pactl set-sink-volume @DEFAULT_SINK@ +5%;
|
||||||
|
vol=$(pactl get-sink-volume @DEFAULT_SINK@ | grep -o '[0-9]\+%' | head -n1);
|
||||||
|
dunstify "Volume Adjusted" "" -h int:value:$vol -r 997
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
bind 122, :none do
|
||||||
|
system 'bash', '-c', %q(
|
||||||
|
pactl set-sink-volume @DEFAULT_SINK@ -5%;
|
||||||
|
vol=$(pactl get-sink-volume @DEFAULT_SINK@ | grep -o '[0-9]\+%' | head -n1);
|
||||||
|
dunstify "Volume Adjusted" "" -h int:value:$vol -r 997
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
bind 121, :none do
|
||||||
|
system 'bash', '-c', %q(
|
||||||
|
pactl set-sink-mute @DEFAULT_SINK@ toggle;
|
||||||
|
vol=$(pactl get-sink-volume @DEFAULT_SINK@ | grep -o '[0-9]\+%' | head -n1);
|
||||||
|
dunstify "Volume Adjusted" "" -h int:value:$vol -r 997
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
bind 232, :none do
|
||||||
|
system 'bash', '-c', %q(
|
||||||
|
brightnessctl set 5%-;
|
||||||
|
pct=$(brightnessctl -m | cut -d, -f4 | tr -d ' %');
|
||||||
|
dunstify "Brightness" "" -h int:value:$pct -r 998
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
bind 233, :none do
|
||||||
|
system 'bash', '-c', %q(
|
||||||
|
brightnessctl set 5%+;
|
||||||
|
pct=$(brightnessctl -m | cut -d, -f4 | tr -d ' %');
|
||||||
|
dunstify "Brightness" "" -h int:value:$pct -r 998
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
bind 'x' do
|
||||||
|
system 'kitty -e fish -c "editor" >/dev/null 2>&1 &'
|
||||||
|
end
|
||||||
|
|
||||||
|
bind 'c' do
|
||||||
|
system 'kitty -e fish -c "y" >/dev/null 2>&1 &'
|
||||||
|
end
|
||||||
|
|
||||||
|
bind 's' do |x|
|
||||||
toggle_float x
|
toggle_float x
|
||||||
end
|
end
|
||||||
|
|
||||||
# ==== Mode switches ====
|
bind 'f' do
|
||||||
|
system 'kitty -e fish -c "btop" >/dev/null 2>&1 &'
|
||||||
bind ?[ do |_, ws|
|
|
||||||
go_special :terminal, ws
|
|
||||||
end
|
end
|
||||||
|
|
||||||
bind ?] do |_, ws|
|
bind '[' do |_, ws|
|
||||||
go_special :misc, ws
|
go_special :term1, ws
|
||||||
end
|
end
|
||||||
|
|
||||||
bind "tab" do |_, ws|
|
bind ']' do |_, ws|
|
||||||
|
go_special :term2, ws
|
||||||
|
end
|
||||||
|
|
||||||
|
bind 79, :none do |_, ws|
|
||||||
go_special :browser, ws
|
go_special :browser, ws
|
||||||
end
|
end
|
||||||
|
|
||||||
bind 89 do |_, ws|
|
bind 89 do |_, ws|
|
||||||
go_special :music, ws
|
go_special :misc, ws
|
||||||
end
|
end
|
||||||
|
|
||||||
bind 81 do |_, ws|
|
bind 118, :none do
|
||||||
go_special :todo, ws
|
system 'bash', '-c',
|
||||||
|
'dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.PlayPause >/dev/null 2>&1 &'
|
||||||
end
|
end
|
||||||
|
|
||||||
# ==== Project navigation ====
|
(0..MAX_PROJECTS - 1).each do |n|
|
||||||
|
bind (n + 1).to_s do
|
||||||
(1..MAX_PROJECTS).each do |n|
|
go_project(n)
|
||||||
bind n.to_s do
|
|
||||||
go_project(n, $current_sub)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
bind 86, :none do |_, ws|
|
bind 86, :none do |_, ws|
|
||||||
next unless in_project?(ws)
|
next unless in_project?(ws)
|
||||||
n = (($current_project - 2) % MAX_PROJECTS) + 1
|
|
||||||
go_project(n, $current_sub)
|
n = (($current - 1 + MAX_PROJECTS) % MAX_PROJECTS)
|
||||||
|
go_project(n)
|
||||||
end
|
end
|
||||||
|
|
||||||
bind 82, :none do |_, ws|
|
bind 82, :none do |_, ws|
|
||||||
next unless in_project?(ws)
|
next unless in_project?(ws)
|
||||||
n = ($current_project % MAX_PROJECTS) + 1
|
|
||||||
go_project(n, $current_sub)
|
|
||||||
end
|
|
||||||
|
|
||||||
bind 79, :none do |_, ws|
|
n = (($current + 1) % MAX_PROJECTS)
|
||||||
next unless in_project?(ws)
|
go_project(n)
|
||||||
go_project($current_project, ($current_sub + 1) % SUBS)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
bind 80, :none do |_, ws|
|
bind 80, :none do |_, ws|
|
||||||
next unless in_project?(ws)
|
next unless in_project?(ws)
|
||||||
go_project($current_project, ($current_sub - 1 + SUBS) % SUBS)
|
|
||||||
|
$p_sub[$current] = $p_sub[$current] == 1 ? 0 : 1
|
||||||
|
go_project($current)
|
||||||
end
|
end
|
||||||
|
|
||||||
# ==== Startup ====
|
go_project(0)
|
||||||
|
|
||||||
go_project(1, 0)
|
|
||||||
|
|||||||
@@ -100,6 +100,8 @@
|
|||||||
ocamlPackages.utop
|
ocamlPackages.utop
|
||||||
ocamlPackages.ocaml-lsp
|
ocamlPackages.ocaml-lsp
|
||||||
ocamlPackages.ocamlformat
|
ocamlPackages.ocamlformat
|
||||||
|
clang-tools
|
||||||
|
solargraph
|
||||||
];
|
];
|
||||||
|
|
||||||
shellHook = ''
|
shellHook = ''
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
opts=" Lock
|
||||||
|
Suspend
|
||||||
|
Shutdown
|
||||||
|
Reboot
|
||||||
|
Hibernate
|
||||||
|
Stop KutuWM"
|
||||||
|
|
||||||
|
sel=$(printf "%s\n" "$opts" | dmenu -i -p "Select Power Option:" \
|
||||||
|
-nf '#e0af68' -nb '#1f2335' -sb '#f7768e' -sf '#1a1b26' -fn 'AgaveNerdFont-16')
|
||||||
|
|
||||||
|
[ -z "$sel" ] && exit 0
|
||||||
|
|
||||||
|
case "$sel" in
|
||||||
|
*Shutdown*)
|
||||||
|
confirm=$(printf "No\nYes" | dmenu -i -p "Are you sure you want to shutdown? :" \
|
||||||
|
-nf '#e0af68' -nb '#1f2335' -sb '#f7768e' -sf '#1a1b26' -fn 'AgaveNerdFont-16')
|
||||||
|
[ "$confirm" = "Yes" ] && exec shutdown -h now
|
||||||
|
;;
|
||||||
|
*Reboot*)
|
||||||
|
confirm=$(printf "No\nYes" | dmenu -i -p "Are you sure you want to reboot? :" \
|
||||||
|
-nf '#e0af68' -nb '#1f2335' -sb '#f7768e' -sf '#1a1b26' -fn 'HurmitNerdFont-16')
|
||||||
|
[ "$confirm" = "Yes" ] && exec reboot
|
||||||
|
;;
|
||||||
|
*Hibernate*)
|
||||||
|
confirm=$(printf "No\nYes" | dmenu -i -p "Are you sure you want to hibernate? :" \
|
||||||
|
-nf '#e0af68' -nb '#1f2335' -sb '#f7768e' -sf '#1a1b26' -fn 'AgaveNerdFont-16')
|
||||||
|
[ "$confirm" = "Yes" ] && exec systemctl --system hibernate
|
||||||
|
;;
|
||||||
|
*Stop\ KutuWM*)
|
||||||
|
#exec kutu-run.rb stop TODO.
|
||||||
|
pkill X
|
||||||
|
;;
|
||||||
|
*Suspend*)
|
||||||
|
exec systemctl --system suspend
|
||||||
|
;;
|
||||||
|
*Lock*)
|
||||||
|
~/dotfiles/scripts/lock.sh &
|
||||||
|
;;
|
||||||
|
esac
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
declare -A aliases=(
|
||||||
|
[editor]="kitty -e fish -c editor"
|
||||||
|
[yazi]="kitty -e fish -c yazi"
|
||||||
|
[btop]="kitty -e fish -c btop"
|
||||||
|
)
|
||||||
|
|
||||||
|
choice=$(
|
||||||
|
{
|
||||||
|
printf '%s\n' "${!aliases[@]}"
|
||||||
|
compgen -c
|
||||||
|
} |
|
||||||
|
grep -v -E '^(\..*|if|fi|case|esac|for|done|while|until|select|function|return|continue|break|time|exec|source|alias|builtin|read|export|unset|local|set|declare|typeset|:|\.|\[|coproc|l|ll|ls|then|else|elif|do|in|\{|\}|!|\[\[|\]\]|_.*|compgen)$' |
|
||||||
|
sort -u |
|
||||||
|
dmenu -i -p "Enter command " \
|
||||||
|
-nf '#4abaaf' -nb '#1f2335' -sb '#7aa2f7' -sf '#102030' -fn 'AgaveNerdFont-16'
|
||||||
|
)
|
||||||
|
|
||||||
|
[ -z "$choice" ] && exit 0
|
||||||
|
|
||||||
|
if [[ -v "aliases[$choice]" ]]; then
|
||||||
|
eval "${aliases[$choice]}" >/dev/null 2>&1 &
|
||||||
|
else
|
||||||
|
"$choice" >/dev/null 2>&1 &
|
||||||
|
fi
|
||||||
|
|
||||||
|
disown
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
xset s off
|
||||||
|
xset -dpms
|
||||||
|
|
||||||
|
xsetroot -cursor_name left_ptr
|
||||||
|
|
||||||
|
setxkbmap us
|
||||||
@@ -17,5 +17,6 @@ let register_callbacks state =
|
|||||||
Window_op.register_toggle_float state;
|
Window_op.register_toggle_float state;
|
||||||
Ws_op.register_jump state;
|
Ws_op.register_jump state;
|
||||||
Ws_op.register_ws_count state;
|
Ws_op.register_ws_count state;
|
||||||
|
Ws_op.register_ws_empty state;
|
||||||
Keybinds.register_bind state;
|
Keybinds.register_bind state;
|
||||||
Keybinds.register_unbind state
|
Keybinds.register_unbind state
|
||||||
|
|||||||
@@ -61,3 +61,28 @@ let register_ws_count (state : Kutu.State.wm_state) =
|
|||||||
Mruby.Bindings.mrb_define_method state.mrb
|
Mruby.Bindings.mrb_define_method state.mrb
|
||||||
(Mruby.Types.Mrb_state.get_object_class state.mrb)
|
(Mruby.Types.Mrb_state.get_object_class state.mrb)
|
||||||
"ws_count" ws_count (Unsigned.UInt32.of_int 0)
|
"ws_count" ws_count (Unsigned.UInt32.of_int 0)
|
||||||
|
|
||||||
|
let register_ws_empty (state : Kutu.State.wm_state) =
|
||||||
|
let mrb_get_args =
|
||||||
|
foreign "mrb_get_args"
|
||||||
|
(ptr Mruby.Types.Mrb_state.typ
|
||||||
|
@-> string
|
||||||
|
@-> ptr Mruby.Types.Mrb_sym.typ
|
||||||
|
@-> returning int)
|
||||||
|
in
|
||||||
|
let ws_empty (mrb : Mruby.Types.Mrb_state.t structure ptr)
|
||||||
|
(self : Mruby.Types.Mrb_value.t structure) =
|
||||||
|
let name = allocate Mruby.Types.Mrb_sym.typ (Unsigned.UInt32.of_int 0) in
|
||||||
|
ignore (mrb_get_args mrb "n" name);
|
||||||
|
let name = Mruby.Bindings.mrb_sym_name mrb !@name in
|
||||||
|
match Hashtbl.find_opt state.workspaces name with
|
||||||
|
| Some ws ->
|
||||||
|
let is_empty = ws.ws_root = None && List.is_empty ws.ws_fwindows in
|
||||||
|
Mruby.Bindings.mrb_bool_value
|
||||||
|
(Unsigned.UInt32.of_int (if is_empty then 1 else 0))
|
||||||
|
| None -> Mruby.Bindings.mrb_bool_value (Unsigned.UInt32.of_int 1)
|
||||||
|
in
|
||||||
|
Mruby.Bindings.mrb_define_method state.mrb
|
||||||
|
(Mruby.Types.Mrb_state.get_object_class state.mrb)
|
||||||
|
"ws_empty?" ws_empty
|
||||||
|
(Mruby.Bindings.mrb_args_req 1)
|
||||||
|
|||||||
+15
-4
@@ -1,16 +1,27 @@
|
|||||||
let () =
|
let () =
|
||||||
let startup_script =
|
let startup_script =
|
||||||
if Array.length Sys.argv <> 2 then None else Some Sys.argv.(1)
|
if Array.length Sys.argv = 2 then Some Sys.argv.(1)
|
||||||
|
else
|
||||||
|
let default =
|
||||||
|
Filename.concat (Sys.getenv "HOME") ".config/kutu/config.rb"
|
||||||
|
in
|
||||||
|
if Sys.file_exists default then Some default else None
|
||||||
in
|
in
|
||||||
|
|
||||||
let state = Kutu.State.new_state in
|
let state = Kutu.State.new_state in
|
||||||
|
|
||||||
print_endline "Started Kutu WM";
|
print_endline "Started Kutu WM";
|
||||||
|
|
||||||
Bindings.Core.register_callbacks state;
|
Bindings.Core.register_callbacks state;
|
||||||
Mruby.Core.mrb_load_string state.mrb Mruby.Initial.initial_code;
|
|
||||||
(match startup_script with
|
(match startup_script with
|
||||||
| None -> ()
|
| Some s ->
|
||||||
| Some s -> Mruby.Core.mrb_load_file state.mrb s);
|
print_string s;
|
||||||
|
print_endline " : Have something";
|
||||||
|
Mruby.Core.mrb_load_string state.mrb (Mruby.Initial.initial_code s)
|
||||||
|
| None ->
|
||||||
|
print_endline "Nothing";
|
||||||
|
Mruby.Core.mrb_load_string state.mrb (Mruby.Initial.initial_code ""));
|
||||||
Mruby.Core.error_check state.mrb;
|
Mruby.Core.error_check state.mrb;
|
||||||
|
|
||||||
if Xcb.Connection.flush state.conn <= 0 then exit 1;
|
if Xcb.Connection.flush state.conn <= 0 then exit 1;
|
||||||
|
|||||||
@@ -28,6 +28,10 @@ let mrb_int_value =
|
|||||||
foreign "kutu_mrb_int_value"
|
foreign "kutu_mrb_int_value"
|
||||||
(ptr Types.Mrb_state.typ @-> uint32_t @-> returning Types.Mrb_value.typ)
|
(ptr Types.Mrb_state.typ @-> uint32_t @-> returning Types.Mrb_value.typ)
|
||||||
|
|
||||||
|
let mrb_bool_value =
|
||||||
|
foreign "kutu_mrb_bool_value"
|
||||||
|
(uint32_t @-> returning Types.Mrb_value.typ)
|
||||||
|
|
||||||
let mrb_intern_cstr =
|
let mrb_intern_cstr =
|
||||||
foreign "mrb_intern_cstr"
|
foreign "mrb_intern_cstr"
|
||||||
(ptr Types.Mrb_state.typ @-> string @-> returning Types.Mrb_sym.typ)
|
(ptr Types.Mrb_state.typ @-> string @-> returning Types.Mrb_sym.typ)
|
||||||
|
|||||||
@@ -12,10 +12,6 @@ let mrb_load_string =
|
|||||||
foreign "mrb_load_string"
|
foreign "mrb_load_string"
|
||||||
(ptr Types.Mrb_state.typ @-> string @-> returning void)
|
(ptr Types.Mrb_state.typ @-> string @-> returning void)
|
||||||
|
|
||||||
let mrb_load_file =
|
|
||||||
foreign "kutu_mrb_load_file"
|
|
||||||
(ptr Types.Mrb_state.typ @-> string @-> returning void)
|
|
||||||
|
|
||||||
let error_check mrb_ptr =
|
let error_check mrb_ptr =
|
||||||
if Types.Mrb_state.has_error mrb_ptr then begin
|
if Types.Mrb_state.has_error mrb_ptr then begin
|
||||||
mrb_print_error mrb_ptr;
|
mrb_print_error mrb_ptr;
|
||||||
|
|||||||
+49
-121
@@ -1,5 +1,6 @@
|
|||||||
let initial_code =
|
let initial_code =
|
||||||
{|#ruby
|
Printf.sprintf
|
||||||
|
{|#ruby
|
||||||
MOD_MAP = {
|
MOD_MAP = {
|
||||||
none: 0,
|
none: 0,
|
||||||
alt: 8,
|
alt: 8,
|
||||||
@@ -12,10 +13,15 @@ KEY_MAP = {
|
|||||||
"e" => 26,
|
"e" => 26,
|
||||||
"r" => 27,
|
"r" => 27,
|
||||||
"f" => 41,
|
"f" => 41,
|
||||||
|
"s" => 39,
|
||||||
|
"a" => 38,
|
||||||
|
"d" => 40,
|
||||||
"n" => 57,
|
"n" => 57,
|
||||||
"b" => 56,
|
"b" => 56,
|
||||||
"m" => 58,
|
"m" => 58,
|
||||||
"v" => 55,
|
"v" => 55,
|
||||||
|
"x" => 53,
|
||||||
|
"c" => 54,
|
||||||
"]" => 35,
|
"]" => 35,
|
||||||
"[" => 34,
|
"[" => 34,
|
||||||
"1" => 10,
|
"1" => 10,
|
||||||
@@ -29,80 +35,10 @@ KEY_MAP = {
|
|||||||
"9" => 18,
|
"9" => 18,
|
||||||
"0" => 19
|
"0" => 19
|
||||||
}
|
}
|
||||||
def bind(key, mod = :super, &block)
|
|
||||||
key_ = key.is_a?(String) ? KEY_MAP[key] : key
|
|
||||||
mod = MOD_MAP[mod]
|
|
||||||
raise "unknown key #{key.to_s}" unless key_
|
|
||||||
raise "unknown modifier" unless mod
|
|
||||||
_bind key_, mod, &block
|
|
||||||
end
|
|
||||||
def unbind(key, mod = :super)
|
|
||||||
key_ = key.is_a?(String) ? KEY_MAP[key] : key
|
|
||||||
mod = MOD_MAP[mod]
|
|
||||||
raise "unknown key #{key.to_s}" unless key_
|
|
||||||
raise "unknown modifier" unless mod
|
|
||||||
_unbind key_, mod
|
|
||||||
end
|
|
||||||
|
|
||||||
# ==== State ====
|
CONFIG_FILE = "%s"
|
||||||
|
|
||||||
MAX_PROJECTS = 9
|
|
||||||
SUBS = 2 # workspaces per project
|
|
||||||
|
|
||||||
$current_project = 1 # 1..MAX_PROJECTS
|
|
||||||
$current_sub = 0 # 0..SUBS-1
|
|
||||||
|
|
||||||
# For each special workspace, remembers which workspace you were on
|
|
||||||
# before you jumped into it -- so hitting the mode key again toggles back.
|
|
||||||
$special_origin = {}
|
|
||||||
|
|
||||||
SPECIAL = {
|
|
||||||
terminal: { cmd: "kitty" },
|
|
||||||
browser: { cmd: "firefox" },
|
|
||||||
music: { cmd: "spotify" },
|
|
||||||
misc: { cmd: nil }, # doesn't start anything
|
|
||||||
todo: { cmd: nil }, # doesn't start anything
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==== Helpers ====
|
|
||||||
|
|
||||||
def project_ws(n, sub)
|
|
||||||
:"p#{n}_#{sub}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def running?(process)
|
|
||||||
system("pgrep -x #{process} > /dev/null 2>&1")
|
|
||||||
end
|
|
||||||
|
|
||||||
def go_project(n, sub)
|
|
||||||
$current_project = n
|
|
||||||
$current_sub = sub
|
|
||||||
jump_ws project_ws(n, sub)
|
|
||||||
end
|
|
||||||
|
|
||||||
def in_project?(ws)
|
|
||||||
!SPECIAL.key?(ws)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Toggle between a special-mode workspace (terminal/browser/music/misc/todo)
|
|
||||||
# and whatever workspace you were last on. Starts the associated app if
|
|
||||||
# it isn't already running. `ws` is the current workspace, passed in by
|
|
||||||
# the bind block (bind gives us (window, current_ws)).
|
|
||||||
def go_special(name, ws)
|
|
||||||
cfg = SPECIAL.fetch(name)
|
|
||||||
|
|
||||||
if ws == name
|
|
||||||
target = $special_origin[name] || project_ws($current_project, $current_sub)
|
|
||||||
jump_ws target
|
|
||||||
else
|
|
||||||
$special_origin[name] = ws
|
|
||||||
jump_ws name
|
|
||||||
system("#{cfg[:cmd]} >/dev/null 2>&1 &") if cfg[:cmd] && !running?(cfg[:cmd])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# ==== Untouched bindings ====
|
|
||||||
|
|
||||||
|
DEFAULT = <<'CODE'
|
||||||
bind ?q do |x|
|
bind ?q do |x|
|
||||||
kill x
|
kill x
|
||||||
end
|
end
|
||||||
@@ -114,64 +50,56 @@ end
|
|||||||
bind ?e do
|
bind ?e do
|
||||||
exit
|
exit
|
||||||
end
|
end
|
||||||
|
CODE
|
||||||
|
|
||||||
bind ?f do |x|
|
BINDINGS = []
|
||||||
toggle_float x
|
SYSTEM_BINDINGS = []
|
||||||
|
|
||||||
|
def bind(key, mod = :super, system: false, &block)
|
||||||
|
key_ = key.is_a?(String) ? KEY_MAP[key] : key
|
||||||
|
mod_ = MOD_MAP[mod]
|
||||||
|
|
||||||
|
raise "unknown key #{key}" unless key_
|
||||||
|
raise "unknown modifier #{mod}" unless mod_
|
||||||
|
|
||||||
|
_bind key_, mod_, &block
|
||||||
|
|
||||||
|
(system ? SYSTEM_BINDINGS : BINDINGS) << [key_, mod_]
|
||||||
end
|
end
|
||||||
|
|
||||||
# ==== Mode switches ====
|
def unbind(key, mod = :super)
|
||||||
|
key_ = key.is_a?(String) ? KEY_MAP[key] : key
|
||||||
|
mod_ = MOD_MAP[mod]
|
||||||
|
|
||||||
bind ?[ do |_, ws|
|
raise "unknown key #{key}" unless key_
|
||||||
go_special :terminal, ws
|
raise "unknown modifier #{mod}" unless mod_
|
||||||
|
|
||||||
|
_unbind key_, mod_
|
||||||
|
BINDINGS.delete([key_, mod_])
|
||||||
end
|
end
|
||||||
|
|
||||||
bind ?] do |_, ws|
|
def unbind_all
|
||||||
go_special :misc, ws
|
BINDINGS.each do |key_, mod_|
|
||||||
|
_unbind key_, mod_
|
||||||
|
end
|
||||||
|
|
||||||
|
BINDINGS.clear
|
||||||
end
|
end
|
||||||
|
|
||||||
bind "tab" do |_, ws|
|
bind ?r, system: true do
|
||||||
go_special :browser, ws
|
unbind_all
|
||||||
end
|
if CONFIG_FILE != ""
|
||||||
|
code = File.read(CONFIG_FILE)
|
||||||
bind 89 do |_, ws|
|
eval code
|
||||||
go_special :music, ws
|
else
|
||||||
end
|
eval DEFAULT
|
||||||
|
|
||||||
bind 81 do |_, ws|
|
|
||||||
go_special :todo, ws
|
|
||||||
end
|
|
||||||
|
|
||||||
# ==== Project navigation ====
|
|
||||||
|
|
||||||
(1..MAX_PROJECTS).each do |n|
|
|
||||||
bind n.to_s do
|
|
||||||
go_project(n, $current_sub)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
bind 86, :none do |_, ws|
|
if CONFIG_FILE != ""
|
||||||
next unless in_project?(ws)
|
code = File.read(CONFIG_FILE)
|
||||||
n = (($current_project - 2) % MAX_PROJECTS) + 1
|
eval code
|
||||||
go_project(n, $current_sub)
|
else
|
||||||
|
eval DEFAULT
|
||||||
end
|
end
|
||||||
|
|
||||||
bind 82, :none do |_, ws|
|
|
||||||
next unless in_project?(ws)
|
|
||||||
n = ($current_project % MAX_PROJECTS) + 1
|
|
||||||
go_project(n, $current_sub)
|
|
||||||
end
|
|
||||||
|
|
||||||
bind 79, :none do |_, ws|
|
|
||||||
next unless in_project?(ws)
|
|
||||||
go_project($current_project, ($current_sub + 1) % SUBS)
|
|
||||||
end
|
|
||||||
|
|
||||||
bind 80, :none do |_, ws|
|
|
||||||
next unless in_project?(ws)
|
|
||||||
go_project($current_project, ($current_sub - 1 + SUBS) % SUBS)
|
|
||||||
end
|
|
||||||
|
|
||||||
# ==== Startup ====
|
|
||||||
|
|
||||||
go_project(1, 0)
|
|
||||||
|}
|
|}
|
||||||
|
|||||||
+17
-23
@@ -1,30 +1,24 @@
|
|||||||
|
#include <mruby.h>
|
||||||
|
#include <mruby/boxing_word.h>
|
||||||
|
#include <mruby/compile.h>
|
||||||
|
#include <mruby/value.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <mruby.h>
|
|
||||||
#include <mruby/value.h>
|
|
||||||
#include <mruby/compile.h>
|
|
||||||
|
|
||||||
mrb_value
|
mrb_value kutu_mrb_int_value(mrb_state *mrb, uint32_t value) {
|
||||||
kutu_mrb_int_value(mrb_state *mrb, uint64_t value)
|
return mrb_int_value(mrb, (mrb_int)value);
|
||||||
{
|
|
||||||
return mrb_int_value(mrb, (mrb_int)value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mrb_value
|
mrb_value kutu_mrb_symbol_value(mrb_sym i) { return mrb_symbol_value(i); }
|
||||||
kutu_mrb_symbol_value(mrb_sym i)
|
|
||||||
{
|
|
||||||
return mrb_symbol_value(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
mrb_value kutu_mrb_bool_value(uint32_t b) { return mrb_bool_value(b); }
|
||||||
kutu_mrb_load_file(mrb_state *mrb, const char *filename)
|
|
||||||
{
|
void kutu_mrb_load_file(mrb_state *mrb, const char *filename) {
|
||||||
FILE *file = fopen(filename, "rb");
|
FILE *file = fopen(filename, "rb");
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
mrb_raisef(mrb, E_RUNTIME_ERROR,
|
mrb_raisef(mrb, E_RUNTIME_ERROR, "could not open file: %s", filename);
|
||||||
"could not open file: %s", filename);
|
return;
|
||||||
return;
|
}
|
||||||
}
|
mrb_load_file(mrb, file);
|
||||||
mrb_load_file(mrb, file);
|
fclose(file);
|
||||||
fclose(file);
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user