feat: wezTerm session_manager
This commit is contained in:
parent
9a6396a898
commit
8cbca7179d
@ -54,8 +54,12 @@ return {
|
|||||||
mods = "LEADER",
|
mods = "LEADER",
|
||||||
action = act.SplitHorizontal({ domain = "CurrentPaneDomain" }),
|
action = act.SplitHorizontal({ domain = "CurrentPaneDomain" }),
|
||||||
},
|
},
|
||||||
},
|
|
||||||
|
|
||||||
|
-- session manager
|
||||||
|
{ key = "s", mods = "LEADER", action = act({ EmitEvent = "save_session" }) },
|
||||||
|
{ key = "l", mods = "LEADER", action = act({ EmitEvent = "load_session" }) },
|
||||||
|
{ key = "r", mods = "LEADER", action = act({ EmitEvent = "restore_session" }) },
|
||||||
|
},
|
||||||
key_tables = {
|
key_tables = {
|
||||||
resize_pane = {
|
resize_pane = {
|
||||||
{ key = "LeftArrow", action = act.AdjustPaneSize({ "Left", 5 }) },
|
{ key = "LeftArrow", action = act.AdjustPaneSize({ "Left", 5 }) },
|
||||||
|
21
.config/wezterm/wezterm-session-manager/LICENSE
Normal file
21
.config/wezterm/wezterm-session-manager/LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2023 danielcopper
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
76
.config/wezterm/wezterm-session-manager/README.md
Normal file
76
.config/wezterm/wezterm-session-manager/README.md
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
# WezTerm Session Manager
|
||||||
|
|
||||||
|
The [WezTerm](https://wezfurlong.org/wezterm/) Session Manager is a Lua script
|
||||||
|
enhancement for WezTerm that provides functionality to save, load, and restore
|
||||||
|
terminal sessions. This tool helps manage terminal sessions, its goal is to save
|
||||||
|
and restore different sessions or better workspaces and later restore them.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **Save Session State** Captures the current layout of windows, tabs and panes,
|
||||||
|
along with their working directories and foreground processes.
|
||||||
|
- **restore Session** Reopens a previously saved session that matches the
|
||||||
|
current workspace name, restoring its layout and directories.
|
||||||
|
- **Load Session (Not implemented yet)** Allows selecting which saved session to
|
||||||
|
load, regardless of the current workspace name.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
1. **Clone the Repository** Clone the Repository into your WezTerm configuration
|
||||||
|
directory:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/danielcopper/wezterm-session-manager.git ~/.config/wezterm/wezterm-session-manager
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Configure WezTerm:** Edit your 'wezterm.lua' file to include the Session
|
||||||
|
Manager:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local session_manager = require("wezterm-session-manager/session-manager")
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Setup Event Bindings:** Edit your 'wezterm.lua' to include the event
|
||||||
|
bindings to trigger the functions of the session manager
|
||||||
|
|
||||||
|
```lua
|
||||||
|
wezterm.on("save_session", function(window) session_manager.save_state(window) end)
|
||||||
|
wezterm.on("load_session", function(window) session_manager.load_state(window) end)
|
||||||
|
wezterm.on("restore_session", function(window) session_manager.restore_state(window) end)
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Set Keybindings:** Define Keybindings in your 'wezterm.lua' for saving,
|
||||||
|
restoring and loading sessions:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local wezterm = require 'wezterm';
|
||||||
|
return {
|
||||||
|
keys = {
|
||||||
|
{key = "S", mods = "LEADER", action = wezterm.action{EmitEvent = "save_session"}},
|
||||||
|
{key = "L", mods = "LEADER", action = wezterm.action{EmitEvent = "load_session"}},
|
||||||
|
{key = "R", mods = "LEADER", action = wezterm.action{EmitEvent = "restore_session"}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
5. I also recommend to set up a keybinding for creating **named** workspaces as
|
||||||
|
explained
|
||||||
|
[here](https://wezfurlong.org/wezterm/config/lua/keyassignment/SwitchToWorkspace.html).
|
||||||
|
This helps managing and switching states.
|
||||||
|
|
||||||
|
## Limitations
|
||||||
|
|
||||||
|
There are currently some limitations and improvements that need to be
|
||||||
|
implemented:
|
||||||
|
|
||||||
|
- The script does not restore the state of running applications within each pane
|
||||||
|
(except nvim on linux which seems to work fine but the general handling should
|
||||||
|
be improved)
|
||||||
|
- It' primarily tested on Linux and Windows, expect some bugs or adjustements
|
||||||
|
that need to be made
|
||||||
|
- Complex pane layouts won't be correctly restored, the current implementation
|
||||||
|
to determine the pane position is extremely basic
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
Feedback, bug reports, and contributions to enhance the script are welcome.
|
233
.config/wezterm/wezterm-session-manager/session-manager.lua
Normal file
233
.config/wezterm/wezterm-session-manager/session-manager.lua
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
local wezterm = require("wezterm")
|
||||||
|
local session_manager = {}
|
||||||
|
local os = wezterm.target_triple
|
||||||
|
|
||||||
|
--- Displays a notification in WezTerm.
|
||||||
|
-- @param message string: The notification message to be displayed.
|
||||||
|
local function display_notification(message)
|
||||||
|
wezterm.log_info(message)
|
||||||
|
-- Additional code to display a GUI notification can be added here if needed
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Retrieves the current workspace data from the active window.
|
||||||
|
-- @return table or nil: The workspace data table or nil if no active window is found.
|
||||||
|
local function retrieve_workspace_data(window)
|
||||||
|
local workspace_name = window:active_workspace()
|
||||||
|
local workspace_data = {
|
||||||
|
name = workspace_name,
|
||||||
|
tabs = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Iterate over tabs in the current window
|
||||||
|
for _, tab in ipairs(window:mux_window():tabs()) do
|
||||||
|
local tab_data = {
|
||||||
|
tab_id = tostring(tab:tab_id()),
|
||||||
|
panes = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Iterate over panes in the current tab
|
||||||
|
for _, pane_info in ipairs(tab:panes_with_info()) do
|
||||||
|
-- Collect pane details, including layout and process information
|
||||||
|
table.insert(tab_data.panes, {
|
||||||
|
pane_id = tostring(pane_info.pane:pane_id()),
|
||||||
|
index = pane_info.index,
|
||||||
|
is_active = pane_info.is_active,
|
||||||
|
is_zoomed = pane_info.is_zoomed,
|
||||||
|
left = pane_info.left,
|
||||||
|
top = pane_info.top,
|
||||||
|
width = pane_info.width,
|
||||||
|
height = pane_info.height,
|
||||||
|
pixel_width = pane_info.pixel_width,
|
||||||
|
pixel_height = pane_info.pixel_height,
|
||||||
|
cwd = tostring(pane_info.pane:get_current_working_dir()),
|
||||||
|
tty = tostring(pane_info.pane:get_foreground_process_name())
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(workspace_data.tabs, tab_data)
|
||||||
|
end
|
||||||
|
|
||||||
|
return workspace_data
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Saves data to a JSON file.
|
||||||
|
-- @param data table: The workspace data to be saved.
|
||||||
|
-- @param file_path string: The file path where the JSON file will be saved.
|
||||||
|
-- @return boolean: true if saving was successful, false otherwise.
|
||||||
|
local function save_to_json_file(data, file_path)
|
||||||
|
if not data then
|
||||||
|
wezterm.log_info("No workspace data to log.")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local file = io.open(file_path, "w")
|
||||||
|
if file then
|
||||||
|
file:write(wezterm.json_encode(data))
|
||||||
|
file:close()
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Recreates the workspace based on the provided data.
|
||||||
|
-- @param workspace_data table: The data structure containing the saved workspace state.
|
||||||
|
local function recreate_workspace(window, workspace_data)
|
||||||
|
local function extract_path_from_dir(working_directory)
|
||||||
|
if os == "x86_64-pc-windows-msvc" then
|
||||||
|
-- On Windows, transform 'file:///C:/path/to/dir' to 'C:/path/to/dir'
|
||||||
|
return working_directory:gsub("file:///", "")
|
||||||
|
elseif os == "x86_64-unknown-linux-gnu" then
|
||||||
|
-- On Linux, transform 'file://{computer-name}/home/{user}/path/to/dir' to '/home/{user}/path/to/dir'
|
||||||
|
return working_directory:gsub("^.*(/home/)", "/home/")
|
||||||
|
else
|
||||||
|
return working_directory:gsub("^.*(/Users/)", "/Users/")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not workspace_data or not workspace_data.tabs then
|
||||||
|
wezterm.log_info("Invalid or empty workspace data provided.")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local tabs = window:mux_window():tabs()
|
||||||
|
|
||||||
|
if #tabs ~= 1 or #tabs[1]:panes() ~= 1 then
|
||||||
|
wezterm.log_info(
|
||||||
|
"Restoration can only be performed in a window with a single tab and a single pane, to prevent accidental data loss.")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local initial_pane = window:active_pane()
|
||||||
|
local foreground_process = initial_pane:get_foreground_process_name()
|
||||||
|
|
||||||
|
-- Check if the foreground process is a shell
|
||||||
|
if foreground_process:find("sh") or foreground_process:find("cmd.exe") or foreground_process:find("powershell.exe") or foreground_process:find("pwsh.exe") or foreground_process:find("nu") then
|
||||||
|
-- Safe to close
|
||||||
|
initial_pane:send_text("exit\r")
|
||||||
|
else
|
||||||
|
wezterm.log_info("Active program detected. Skipping exit command for initial pane.")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Recreate tabs and panes from the saved state
|
||||||
|
for _, tab_data in ipairs(workspace_data.tabs) do
|
||||||
|
local cwd_uri = tab_data.panes[1].cwd
|
||||||
|
local cwd_path = extract_path_from_dir(cwd_uri)
|
||||||
|
|
||||||
|
local new_tab = window:mux_window():spawn_tab({ cwd = cwd_path })
|
||||||
|
if not new_tab then
|
||||||
|
wezterm.log_info("Failed to create a new tab.")
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Activate the new tab before creating panes
|
||||||
|
new_tab:activate()
|
||||||
|
|
||||||
|
-- Recreate panes within this tab
|
||||||
|
for j, pane_data in ipairs(tab_data.panes) do
|
||||||
|
local new_pane
|
||||||
|
if j == 1 then
|
||||||
|
new_pane = new_tab:active_pane()
|
||||||
|
else
|
||||||
|
local direction = 'Right'
|
||||||
|
if pane_data.left == tab_data.panes[j - 1].left then
|
||||||
|
direction = 'Bottom'
|
||||||
|
end
|
||||||
|
|
||||||
|
new_pane = new_tab:active_pane():split({
|
||||||
|
direction = direction,
|
||||||
|
cwd = extract_path_from_dir(pane_data.cwd)
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
if not new_pane then
|
||||||
|
wezterm.log_info("Failed to create a new pane.")
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Restore TTY for Neovim on Linux
|
||||||
|
-- NOTE: cwd is handled differently on windows. maybe extend functionality for windows later
|
||||||
|
-- This could probably be handled better in general
|
||||||
|
if not (os == "x86_64-pc-windows-msvc") then
|
||||||
|
if not (os == "x86_64-pc-windows-msvc") and pane_data.tty:sub(- #"/bin/nvim") == "/bin/nvim" then
|
||||||
|
new_pane:send_text(pane_data.tty .. " ." .. "\n")
|
||||||
|
else
|
||||||
|
-- TODO - With running npm commands (e.g a running web client) this seems to execute Node, without the arguments
|
||||||
|
new_pane:send_text(pane_data.tty .. "\n")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
wezterm.log_info("Workspace recreated with new tabs and panes based on saved state.")
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Loads data from a JSON file.
|
||||||
|
-- @param file_path string: The file path from which the JSON data will be loaded.
|
||||||
|
-- @return table or nil: The loaded data as a Lua table, or nil if loading failed.
|
||||||
|
local function load_from_json_file(file_path)
|
||||||
|
local file = io.open(file_path, "r")
|
||||||
|
if not file then
|
||||||
|
wezterm.log_info("Failed to open file: " .. file_path)
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local file_content = file:read("*a")
|
||||||
|
file:close()
|
||||||
|
|
||||||
|
local data = wezterm.json_parse(file_content)
|
||||||
|
if not data then
|
||||||
|
wezterm.log_info("Failed to parse JSON data from file: " .. file_path)
|
||||||
|
end
|
||||||
|
return data
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Loads the saved json file matching the current workspace.
|
||||||
|
function session_manager.restore_state(window)
|
||||||
|
local workspace_name = window:active_workspace()
|
||||||
|
local file_path = wezterm.home_dir ..
|
||||||
|
"/.config/wezterm/wezterm-session-manager/wezterm_state_" .. workspace_name .. ".json"
|
||||||
|
|
||||||
|
local workspace_data = load_from_json_file(file_path)
|
||||||
|
if not workspace_data then
|
||||||
|
window:toast_notification('WezTerm',
|
||||||
|
'Workspace state file not found for workspace: ' .. workspace_name, nil, 4000)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if recreate_workspace(window, workspace_data) then
|
||||||
|
window:toast_notification('WezTerm', 'Workspace state loaded for workspace: ' .. workspace_name,
|
||||||
|
nil, 4000)
|
||||||
|
else
|
||||||
|
window:toast_notification('WezTerm', 'Workspace state loading failed for workspace: ' .. workspace_name,
|
||||||
|
nil, 4000)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Allows to select which workspace to load
|
||||||
|
function session_manager.load_state(window)
|
||||||
|
-- TODO: Implement
|
||||||
|
-- Placeholder for user selection logic
|
||||||
|
-- ...
|
||||||
|
-- TODO: Call the function recreate_workspace(workspace_data) to recreate the workspace
|
||||||
|
-- Placeholder for recreation logic...
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Orchestrator function to save the current workspace state.
|
||||||
|
-- Collects workspace data, saves it to a JSON file, and displays a notification.
|
||||||
|
function session_manager.save_state(window)
|
||||||
|
local data = retrieve_workspace_data(window)
|
||||||
|
|
||||||
|
-- Construct the file path based on the workspace name
|
||||||
|
local file_path = wezterm.home_dir .. "/.config/wezterm/wezterm-session-manager/wezterm_state_" .. data.name .. ".json"
|
||||||
|
|
||||||
|
-- Save the workspace data to a JSON file and display the appropriate notification
|
||||||
|
if save_to_json_file(data, file_path) then
|
||||||
|
window:toast_notification('WezTerm Session Manager', 'Workspace state saved successfully', nil, 4000)
|
||||||
|
else
|
||||||
|
window:toast_notification('WezTerm Session Manager', 'Failed to save workspace state', nil, 4000)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return session_manager
|
@ -0,0 +1 @@
|
|||||||
|
{"name":"default","tabs":[{"panes":[{"cwd":"file://nabu.local/Users/paramah","height":39,"index":0,"is_active":false,"is_zoomed":false,"left":0,"pane_id":"0","pixel_height":1053,"pixel_width":3552,"top":0,"tty":"/opt/homebrew/Cellar/neovim/0.11.0/bin/nvim","width":296},{"cwd":"file://nabu.local/Users/paramah","height":39,"index":1,"is_active":true,"is_zoomed":false,"left":0,"pane_id":"1","pixel_height":1053,"pixel_width":3552,"top":40,"tty":"/bin/zsh","width":296}],"tab_id":"0"}]}
|
@ -1,5 +1,6 @@
|
|||||||
local wezterm = require("wezterm")
|
local wezterm = require("wezterm")
|
||||||
local mappings = require("modules.mappings")
|
local mappings = require("modules.mappings")
|
||||||
|
local session_manager = require("wezterm-session-manager/session-manager")
|
||||||
|
|
||||||
-- Show which key table is active in the status area
|
-- Show which key table is active in the status area
|
||||||
wezterm.on("update-right-status", function(window, pane)
|
wezterm.on("update-right-status", function(window, pane)
|
||||||
@ -10,9 +11,19 @@ wezterm.on("update-right-status", function(window, pane)
|
|||||||
window:set_right_status(name or "")
|
window:set_right_status(name or "")
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
wezterm.on("save_session", function(window)
|
||||||
|
session_manager.save_state(window)
|
||||||
|
end)
|
||||||
|
wezterm.on("load_session", function(window)
|
||||||
|
session_manager.load_state(window)
|
||||||
|
end)
|
||||||
|
wezterm.on("restore_session", function(window)
|
||||||
|
session_manager.restore_state(window)
|
||||||
|
end)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
default_cursor_style = "BlinkingBlock",
|
default_cursor_style = "BlinkingBlock",
|
||||||
color_scheme = "Poimandres",
|
color_scheme = "Catppuccin Mocha",
|
||||||
colors = {
|
colors = {
|
||||||
cursor_bg = "#A6ACCD",
|
cursor_bg = "#A6ACCD",
|
||||||
cursor_border = "#A6ACCD",
|
cursor_border = "#A6ACCD",
|
||||||
@ -26,7 +37,7 @@ return {
|
|||||||
-- tab bar
|
-- tab bar
|
||||||
use_fancy_tab_bar = true,
|
use_fancy_tab_bar = true,
|
||||||
tab_bar_at_bottom = false,
|
tab_bar_at_bottom = false,
|
||||||
hide_tab_bar_if_only_one_tab = true,
|
hide_tab_bar_if_only_one_tab = false,
|
||||||
tab_max_width = 999999,
|
tab_max_width = 999999,
|
||||||
window_padding = {
|
window_padding = {
|
||||||
left = 7,
|
left = 7,
|
||||||
|
25
.gitconfig
25
.gitconfig
@ -1,6 +1,4 @@
|
|||||||
# This is Git's per-user configuration file.
|
|
||||||
[user]
|
[user]
|
||||||
# Please adapt and uncomment the following lines:
|
|
||||||
name = Aleksander Cynarski
|
name = Aleksander Cynarski
|
||||||
email = aleksander@cynarski.pl
|
email = aleksander@cynarski.pl
|
||||||
|
|
||||||
@ -13,13 +11,6 @@
|
|||||||
reflog = delta
|
reflog = delta
|
||||||
show = delta
|
show = delta
|
||||||
|
|
||||||
# Delta settings
|
|
||||||
# [delta]
|
|
||||||
# features = side-by-side line-numbers decorations
|
|
||||||
# syntax-theme = Dracula
|
|
||||||
# plus-style = syntax "#003800"
|
|
||||||
# minus-style = syntax "#3f0001"
|
|
||||||
|
|
||||||
[delta]
|
[delta]
|
||||||
plus-style = "syntax #012800"
|
plus-style = "syntax #012800"
|
||||||
minus-style = "syntax #340001"
|
minus-style = "syntax #340001"
|
||||||
@ -27,4 +18,20 @@
|
|||||||
navigate = true
|
navigate = true
|
||||||
side-by-side = true
|
side-by-side = true
|
||||||
|
|
||||||
|
[pretty]
|
||||||
|
slim = "%C(red)%h%C(yellow)%d%C(reset) %s %C(green)(%cd) %C(bold blue)<%an>%C(reset)"
|
||||||
|
|
||||||
|
[alias]
|
||||||
|
lg1 = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all
|
||||||
|
lg2 = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n'' %C(white)%s%C(reset) %C(dim white)- %an%C(reset)' --all
|
||||||
|
; lg = !"git lg2"
|
||||||
|
tree = "forest --pretty=format:\"%C(red)%h %C(magenta)(%ar) %C(blue)%an %C(reset)%s\" --style=15 --reverse"
|
||||||
|
lg = log --graph --pretty=slim --abbrev-commit --date=relative
|
||||||
|
; lg date: sorted by date and with absolute dates
|
||||||
|
lgd = log --graph --pretty=slim --abbrev-commit --date=local --date-order
|
||||||
|
; lg upstream: also show upstream branch
|
||||||
|
lgu = !git lg $( git rev-parse --symbolic @{u} ) HEAD
|
||||||
|
; lg date, upstream
|
||||||
|
lgdu = !git lgd $( git rev-parse --symbolic @{u} ) HEAD
|
||||||
|
; lg me: my commits from all branches, by date
|
||||||
|
lgme = !git lgd --author=\"$( git config --get user.name )\" --all
|
||||||
|
Loading…
x
Reference in New Issue
Block a user