Skip to content

feat: Add Windows compatibility #46

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 93 additions & 26 deletions nbs/00_core.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,15 @@
"source": [
"#| export\n",
"def _aliases(shell):\n",
" return co([shell, '-ic', 'alias'], text=True).strip()"
" try:\n",
" if sys.platform == 'win32':\n",
" try:\n",
" return co(['powershell', '-Command', 'Get-Alias'], text=True).strip()\n",
" except:\n",
" return \"Windows aliases not available\"\n",
" return co([shell, '-ic', 'alias'], text=True).strip()\n",
" except:\n",
" return \"Aliases not available\"\n"
]
},
{
Expand All @@ -289,13 +297,22 @@
"source": [
"#| export\n",
"def _sys_info():\n",
" sys = co(['uname', '-a'], text=True).strip()\n",
" ssys = f'<system>{sys}</system>'\n",
" shell = co('echo $SHELL', shell=True, text=True).strip()\n",
" sshell = f'<shell>{shell}</shell>'\n",
" aliases = _aliases(shell)\n",
" saliases = f'<aliases>\\n{aliases}\\n</aliases>'\n",
" return f'<system_info>\\n{ssys}\\n{sshell}\\n{saliases}\\n</system_info>'"
" try:\n",
" if sys.platform == 'win32':\n",
" sys_info = co(['systeminfo'], text=True).strip()\n",
" ssys = f'<system>Windows: {sys_info}</system>'\n",
" shell = os.environ.get('SHELL') or os.environ.get('ComSpec', 'cmd.exe')\n",
" else:\n",
" sys_info = co(['uname', '-a'], text=True).strip()\n",
" ssys = f'<system>{sys_info}</system>'\n",
" shell = co('echo $SHELL', shell=True, text=True).strip()\n",
" \n",
" sshell = f'<shell>{shell}</shell>'\n",
" aliases = _aliases(shell)\n",
" saliases = f'<aliases>\\n{aliases}\\n</aliases>'\n",
" return f'<system_info>\\n{ssys}\\n{sshell}\\n{saliases}\\n</system_info>'\n",
" except Exception as e:\n",
" return f'<system_info>\\n<system>System info not available: {str(e)}</system>\\n</system_info>'"
]
},
{
Expand All @@ -316,6 +333,22 @@
"## Tmux"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f6e43e12",
"metadata": {},
"outputs": [],
"source": [
"#| export\n",
"def is_tmux_available():\n",
" try:\n",
" co(['tmux', 'has-session'], stderr=subprocess.DEVNULL)\n",
" return True\n",
" except (subprocess.CalledProcessError, FileNotFoundError):\n",
" return False"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand All @@ -326,9 +359,13 @@
"#| export\n",
"def get_pane(n, pid=None):\n",
" \"Get output from a tmux pane\"\n",
" cmd = ['tmux', 'capture-pane', '-p', '-S', f'-{n}']\n",
" if pid: cmd += ['-t', pid]\n",
" return co(cmd, text=True)"
" if not is_tmux_available(): return None\n",
" try:\n",
" cmd = ['tmux', 'capture-pane', '-p', '-S', f'-{n}']\n",
" if pid: cmd += ['-t', pid]\n",
" return co(cmd, text=True)\n",
" except subprocess.CalledProcessError:\n",
" return None"
]
},
{
Expand All @@ -351,9 +388,13 @@
"source": [
"#| export\n",
"def get_panes(n):\n",
" cid = co(['tmux', 'display-message', '-p', '#{pane_id}'], text=True).strip()\n",
" pids = [p for p in co(['tmux', 'list-panes', '-F', '#{pane_id}'], text=True).splitlines()] \n",
" return '\\n'.join(f\"<pane id={p} {'active' if p==cid else ''}>{get_pane(n, p)}</pane>\" for p in pids) "
" if not is_tmux_available(): return None\n",
" try:\n",
" cid = co(['tmux', 'display-message', '-p', '#{pane_id}'], text=True).strip()\n",
" pids = [p for p in co(['tmux', 'list-panes', '-F', '#{pane_id}'], text=True).splitlines()] \n",
" return '\\n'.join(f\"<pane id={p} {'active' if p==cid else ''}>{get_pane(n, p)}</pane>\" for p in pids)\n",
" except subprocess.CalledProcessError:\n",
" return None"
]
},
{
Expand Down Expand Up @@ -397,8 +438,12 @@
"source": [
"#| export\n",
"def tmux_history_lim():\n",
" lim = co(['tmux', 'display-message', '-p', '#{history-limit}'], text=True).strip()\n",
" return int(lim) if lim.isdigit() else 3000\n"
" if not is_tmux_available(): return 2000\n",
" try:\n",
" lim = co(['tmux', 'display-message', '-p', '#{history-limit}'], text=True).strip()\n",
" return int(lim) if lim.isdigit() else 3000\n",
" except (subprocess.CalledProcessError, ValueError):\n",
" return 2000"
]
},
{
Expand All @@ -422,6 +467,23 @@
"tmux_history_lim()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a0648292",
"metadata": {},
"outputs": [],
"source": [
"#| export\n",
"def get_powershell_history(n):\n",
" \"Get history from PowerShell\"\n",
" try:\n",
" cmd = ['powershell', '-Command', f'Get-History -Count {n} | Format-List CommandLine,Status']\n",
" return co(cmd, text=True).strip()\n",
" except (subprocess.CalledProcessError, FileNotFoundError):\n",
" return None"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand All @@ -431,11 +493,16 @@
"source": [
"#| export\n",
"def get_history(n, pid='current'):\n",
" try:\n",
" if pid=='current': return get_pane(n)\n",
" if pid=='all': return get_panes(n)\n",
" return get_pane(n, pid)\n",
" except subprocess.CalledProcessError: return None"
" if is_tmux_available():\n",
" try:\n",
" if pid=='current': return get_pane(n)\n",
" if pid=='all': return get_panes(n)\n",
" return get_pane(n, pid)\n",
" except subprocess.CalledProcessError:\n",
" return None\n",
" elif sys.platform == 'win32':\n",
" return get_powershell_history(n)\n",
" return None"
]
},
{
Expand Down Expand Up @@ -813,7 +880,7 @@
"\n",
" if mode not in ['default', 'command', 'agent', 'sassy']:\n",
" raise Exception(f\"{mode} is not valid. Must be one of the following: ['default', 'command', 'agent', 'sassy']\")\n",
" if mode == 'command' and os.environ.get('TMUX') is None:\n",
" if mode == 'command' and not is_tmux_available():\n",
" raise Exception('Must be in a tmux session to use command mode.')\n",
"\n",
" if verbosity > 0: print(f\"{datetime.now()} | Starting ShellSage request with options {opts}\")\n",
Expand All @@ -823,11 +890,11 @@
" query = ' '.join(query)\n",
" ctxt = '' if skip_system else _sys_info()\n",
"\n",
" # Get tmux history if in a tmux session\n",
" if os.environ.get('TMUX'):\n",
" if verbosity > 0: print(f\"{datetime.now()} | Adding TMUX history to prompt\")\n",
" # Get history from tmux or PowerShell\n",
" if is_tmux_available() or sys.platform == 'win32':\n",
" if verbosity > 0: print(f\"{datetime.now()} | Adding terminal history to prompt\")\n",
" if opts.history_lines is None or opts.history_lines < 0:\n",
" opts.history_lines = tmux_history_lim()\n",
" opts.history_lines = tmux_history_lim() if is_tmux_available() else 50\n",
" history = get_history(opts.history_lines, pid)\n",
" if history: ctxt += f'<terminal_history>\\n{history}\\n</terminal_history>'\n",
"\n",
Expand Down
2 changes: 2 additions & 0 deletions shell_sage/_modidx.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
'shell_sage.core.get_opts': ('core.html#get_opts', 'shell_sage/core.py'),
'shell_sage.core.get_pane': ('core.html#get_pane', 'shell_sage/core.py'),
'shell_sage.core.get_panes': ('core.html#get_panes', 'shell_sage/core.py'),
'shell_sage.core.get_powershell_history': ('core.html#get_powershell_history', 'shell_sage/core.py'),
'shell_sage.core.get_res': ('core.html#get_res', 'shell_sage/core.py'),
'shell_sage.core.get_sage': ('core.html#get_sage', 'shell_sage/core.py'),
'shell_sage.core.is_tmux_available': ('core.html#is_tmux_available', 'shell_sage/core.py'),
'shell_sage.core.main': ('core.html#main', 'shell_sage/core.py'),
'shell_sage.core.mk_db': ('core.html#mk_db', 'shell_sage/core.py'),
'shell_sage.core.tmux_history_lim': ('core.html#tmux_history_lim', 'shell_sage/core.py'),
Expand Down
Loading