From 271bbddc81afd3a58a201d1cd8b455a01d18ad67 Mon Sep 17 00:00:00 2001 From: Nick Barcet Date: Thu, 18 Dec 2008 10:49:01 +0100 Subject: [PATCH 1/9] First try at screen-profile-helper --- debian/changelog | 1 + debian/control | 2 +- debian/install | 1 + profiles/common | 2 +- screen-profiles-helper.py | 105 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 screen-profiles-helper.py diff --git a/debian/changelog b/debian/changelog index c85579a3..1320fb02 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,6 +4,7 @@ screen-profiles (1.1-0ubuntu1) jaunty; urgency=low * Key binding framework basis * Added some sensible key bindings * First pot and translation to french + * First try at screen-profile-helper [ Dustin Kirkland ] * created keybindings directory, moved keybindings there diff --git a/debian/control b/debian/control index 832a919a..e2823af1 100644 --- a/debian/control +++ b/debian/control @@ -9,7 +9,7 @@ Vcs-Bzr: http://bazaar.launchpad.net/~kirkland/screen-profiles/main Package: screen-profiles Architecture: all -Depends: debconf (>= 0.5) | debconf-2.0, screen, gettext-base, debianutils +Depends: debconf (>= 0.5) | debconf-2.0, screen, gettext-base, debianutils, python-dialog Recommends: update-notifier-common Suggests: bc Description: a set of useful profiles and a profile-switcher for GNU screen diff --git a/debian/install b/debian/install index 0a6579c5..06238c27 100644 --- a/debian/install +++ b/debian/install @@ -8,3 +8,4 @@ profiles/debian.screenrc usr/share/screen-profiles/profiles profiles/ubuntu.screenrc usr/share/screen-profiles/profiles keybindings/common usr/share/screen-profiles/keybindings select-screen-profile usr/bin +screen-profiles-helper.py usr/share/screen-profiles/ diff --git a/profiles/common b/profiles/common index 6a0da013..555502ad 100644 --- a/profiles/common +++ b/profiles/common @@ -36,7 +36,7 @@ defscrollback 10000 # Default windows screen -t bash 1 -screen -t welcome 0 /usr/bin/sensible-pager /usr/share/doc/screen-profiles/help.txt +screen -t welcome 0 python /usr/share/screen-profiles/screen-profiles-helper.py # Default keybindings source /usr/share/screen-profiles/keybindings/common diff --git a/screen-profiles-helper.py b/screen-profiles-helper.py new file mode 100644 index 00000000..0a490957 --- /dev/null +++ b/screen-profiles-helper.py @@ -0,0 +1,105 @@ +#! /usr/bin/env python + +import sys, os, os.path, time, string, dialog + +def ioctl_GWINSZ(fd): #### TABULATION FUNCTIONS + try: ### Discover terminal width + import fcntl, termios, struct, os + cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234')) + except: + return None + return cr + +def terminal_size(): ### decide on *some* terminal size + cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2) # try open fds + if not cr: # ...then ctty + try: + fd = os.open(os.ctermid(), os.O_RDONLY) + cr = ioctl_GWINSZ(fd) + os.close(fd) + except: + pass + if not cr: # env vars or finally defaults + try: + cr = (env['LINES'], env['COLUMNS']) + except: + cr = (25, 80) + return int(cr[1]-5), int(cr[0]-5) # reverse rows, cols + + +def handle_exit_code(d, code): + # d is supposed to be a Dialog instance + if code in (d.DIALOG_CANCEL, d.DIALOG_ESC): + if code == d.DIALOG_CANCEL: + msg = "You chose cancel. Do you want to " \ + "exit this program?" + else: + msg = "You pressed ESC. Do you want to " \ + "exit this program?" + # "No" or "ESC" will bring the user back to the demo. + # DIALOG_ERROR is propagated as an exception and caught in main(). + # So we only need to handle OK here. + if d.yesno(msg) == d.DIALOG_OK: + sys.exit(0) + return 0 + else: + return 1 # code is d.DIALOG_OK + +def menu_demo(d, size): + while 1: + (code, tag) = d.menu( + "Please chose an action", + width=size[0], + choices=[("1", "Display some basic help"), + ("2", "Change screen profile"), + ("3", "Change key bindings"), + ("4", "Launch screen by default") + ]) + if handle_exit_code(d, code): + break + return tag + +def help(d, size): + d.textbox("/usr/share/doc/screen-profiles/help.txt", width=size[0], height=size[1]) + +def profile(d): + d.msgbox("This has yet to be implemented") + +def key(d): + d.msgbox("This has yet to be implemented") + +def default(d): + d.msgbox("This has yet to be implemented") + +def main(): + """This is the main loop of our screen helper. + + """ + size = terminal_size() + + try: + d = dialog.Dialog(dialog="dialog") + d.add_persistent_args(["--backtitle", "GNU Screen profiles helper"]) + + help(d, size) + + while True: + tag = menu_demo(d, size) + if tag == "1": + help (d, size) + elif tag == "2": + profile(d) + elif tag == "3": + key(d) + elif tag == "4": + default(d) + + except dialog.error, exc_instance: + sys.stderr.write("Error:\n\n%s\n" % exc_instance.complete_message()) + sys.stderr.write("%s\n" % dialog.error) + sys.exit(1) + + sys.exit(0) + + +if __name__ == "__main__": main() From e7db8eb470288cb583904b98ffc01864a2d40aed Mon Sep 17 00:00:00 2001 From: Nick Barcet Date: Fri, 19 Dec 2008 15:04:26 +0100 Subject: [PATCH 2/9] Allow select-screen-profiles to not run interactively --- debian/changelog | 1 + select-screen-profile | 184 ++++++++++++++++++++++++++++++------------ 2 files changed, 135 insertions(+), 50 deletions(-) diff --git a/debian/changelog b/debian/changelog index 1320fb02..59466364 100644 --- a/debian/changelog +++ b/debian/changelog @@ -5,6 +5,7 @@ screen-profiles (1.1-0ubuntu1) jaunty; urgency=low * Added some sensible key bindings * First pot and translation to french * First try at screen-profile-helper + * Allow select-screen-profile to not run interactively [ Dustin Kirkland ] * created keybindings directory, moved keybindings there diff --git a/select-screen-profile b/select-screen-profile index 0daf28a5..7692b94e 100755 --- a/select-screen-profile +++ b/select-screen-profile @@ -1,10 +1,44 @@ #!/bin/sh -e +# +# GNU screen-profiles +# Copyright (C) 2008 Canonical Ltd. +# +# Authors: Dustin Kirklan +# Nick Barcet +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + # To generate localization information, run: # xgettext -o - -L Shell select-screen-profile +usage () { + cat </dev/null; then - read -p "`gettext 'Choose: '` 1-$i [$simple]: " -r selected - elif ! test $selected -le $i 2>/dev/null; then - read -p "`gettext 'Choose: '` 1-$i [$simple]: " -r selected - else - break - fi -done +profiles=$(ls $PROFILE_DIR) -i=0 -for x in $profiles; do - i=`expr $i + 1` - if [ $i -eq $selected ]; then - if [ ! -e "$HOME/.screenrc" ]; then - # If the user doesn't have a .screenrc, seed one - echo "source ~/.screenrc-profile" > "$HOME/.screenrc" - else - # If the user does have a .screenrc, see if it has the - # source line - if ! grep -qs "source $HOME/.screenrc-profile" "$HOME/.screenrc"; then - # And if it's missing the source line, add it - # to the top - tmp=`mktemp "$HOME/.screenrc.XXXXXX"` - echo "source $HOME/.screenrc-profile" > "$tmp" - cat "$HOME/.screenrc" >> "$tmp" - mv -f "$tmp" "$HOME/.screenrc" - fi - fi - rm -f "$HOME/.screenrc-profile" - ln -s "$PROFILE_DIR/$x" "$HOME/.screenrc-profile" - fi -done +prompt() { + # Prompt the user to choose among the available profiles + echo + echo `gettext "Select a screen profile: "` + i=0 + + for x in $profiles; do + i=$(expr $i + 1) + desc=" " + if [ $x = "ubuntu.screenrc" ]; then + desc="<---- ` gettext 'recommended'`" + simple=$i + fi + echo " $i. $x\t\t$desc" + done + echo + selected=x + while /bin/true; do + if [ -z "$selected" -a ! -z "$simple" ]; then + selected="$simple" + elif ! test $selected -gt 0 2>/dev/null; then + read -p "`gettext 'Choose: '` 1-$i [$simple]: " -r selected + elif ! test $selected -le $i 2>/dev/null; then + read -p "`gettext 'Choose: '` 1-$i [$simple]: " -r selected + else + break + fi + done +} + +listprofiles() { + for x in $profiles; do + echo "$x" + done +} + +setprofile() { + i=0 + found=0 + for x in $profiles; do + i=`expr $i + 1` + if [ $i -eq $selected ] || [ "$profile" = $x ] ; then + if [ ! -e "$HOME/.screenrc" ]; then + # If the user doesn't have a .screenrc, seed one + echo "source ~/.screenrc-profile" > "$HOME/.screenrc" + else + # If the user does have a .screenrc, see if it has the + # source line + if ! grep -qs "source $HOME/.screenrc-profile" "$HOME/.screenrc"; then + # And if it's missing the source line, add it + # to the top + tmp=`mktemp "$HOME/.screenrc.XXXXXX"` + echo "source $HOME/.screenrc-profile" > "$tmp" + cat "$HOME/.screenrc" >> "$tmp" + mv -f "$tmp" "$HOME/.screenrc" + fi + fi + rm -f "$HOME/.screenrc-profile" + ln -s "$PROFILE_DIR/$x" "$HOME/.screenrc-profile" + found=1 + fi + done + if [ $found -eq 0 ]; then + echo "Invalid profile name" + fi +} + +if [ $# -eq 0 ]; then + prompt + setprofile +else + TEMP=`getopt -o lhs: --long list,help,set: -- "$@"` + eval set -- "$TEMP" + + while true + do + case "$1" in + -s|--set) + profile="$2" + setprofile + shift 2 + break + ;; + -l|--list) + listprofiles + shift + break + ;; + *) + usage() + exit 1 + ;; + --) + shift + break + ;; + esac + done +fi exit 0 From 78d0900d2d550398953ca2a10f1cbe0b8bf5d2dc Mon Sep 17 00:00:00 2001 From: Nick Barcet Date: Fri, 19 Dec 2008 18:46:17 +0100 Subject: [PATCH 3/9] * screen-profile-helper allows to create new windows * screen-profile-helper allows to select profiles --- debian/changelog | 2 ++ debian/install | 1 + keybindings/common | 4 ++++ profiles/common | 4 ---- screen-profiles-helper.py | 27 +++++++++++++++------ select-screen-profile | 49 ++++++++++++++++++++++++++++----------- windows/default | 3 +++ 7 files changed, 66 insertions(+), 24 deletions(-) create mode 100644 windows/default diff --git a/debian/changelog b/debian/changelog index 59466364..cca97c8a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -6,6 +6,8 @@ screen-profiles (1.1-0ubuntu1) jaunty; urgency=low * First pot and translation to french * First try at screen-profile-helper * Allow select-screen-profile to not run interactively + * screen-profile-helper allows to create new windows + * screen-profile-helper allows to select profiles [ Dustin Kirkland ] * created keybindings directory, moved keybindings there diff --git a/debian/install b/debian/install index 06238c27..f506ae65 100644 --- a/debian/install +++ b/debian/install @@ -7,5 +7,6 @@ profiles/common usr/share/screen-profiles/profiles profiles/debian.screenrc usr/share/screen-profiles/profiles profiles/ubuntu.screenrc usr/share/screen-profiles/profiles keybindings/common usr/share/screen-profiles/keybindings +windows/default usr/share/screen-profiles/windows select-screen-profile usr/bin screen-profiles-helper.py usr/share/screen-profiles/ diff --git a/keybindings/common b/keybindings/common index 2d5c569c..f1fe27f9 100644 --- a/keybindings/common +++ b/keybindings/common @@ -40,6 +40,10 @@ bindkey -k k6 kill # F6 | Close window bindkey -k k1 screen -t help 0 less /usr/share/doc/screen-profiles/help.txt # F1 | Basic help (this) bindkey -k k2 help # F2 | Advanced help +# Reload +register r "^g:source $HOME/.screenrc-profile" +bindkey -k k5 process r + # power detach register x "^g^d D" bindkey ^[[3;6~ process x # C-shift-del | Detach and logout diff --git a/profiles/common b/profiles/common index 555502ad..aecf8c9d 100644 --- a/profiles/common +++ b/profiles/common @@ -34,9 +34,5 @@ hardstatus alwayslastline termcapinfo xterm ti@:te@ defscrollback 10000 -# Default windows -screen -t bash 1 -screen -t welcome 0 python /usr/share/screen-profiles/screen-profiles-helper.py - # Default keybindings source /usr/share/screen-profiles/keybindings/common diff --git a/screen-profiles-helper.py b/screen-profiles-helper.py index 0a490957..a7d936ec 100644 --- a/screen-profiles-helper.py +++ b/screen-profiles-helper.py @@ -1,6 +1,6 @@ #! /usr/bin/env python -import sys, os, os.path, time, string, dialog +import sys, os, os.path, time, string, dialog, commands def ioctl_GWINSZ(fd): #### TABULATION FUNCTIONS try: ### Discover terminal width @@ -52,8 +52,8 @@ def menu_demo(d, size): width=size[0], choices=[("1", "Display some basic help"), ("2", "Change screen profile"), - ("3", "Change key bindings"), - ("4", "Launch screen by default") + ("3", "Create a new window"), + ("4", "Install screen by default at login") ]) if handle_exit_code(d, code): break @@ -63,10 +63,23 @@ def help(d, size): d.textbox("/usr/share/doc/screen-profiles/help.txt", width=size[0], height=size[1]) def profile(d): - d.msgbox("This has yet to be implemented") + list = [] + for choice in commands.getoutput('select-screen-profile -l').splitlines(): + if choice.startswith("ubuntu"): + el = (choice, "<-- recommended", 1) + list.append(el) + else: + el = (choice, "", 0) + list.append(el) + (code, tag) = d.radiolist("Which profile would you like to use?", width=65, choices=list) + if code == d.DIALOG_OK: + commands.getoutput('select-screen-profile --set %s' % tag) + d.msgbox("Please press F5 to apply profile") -def key(d): - d.msgbox("This has yet to be implemented") +def newwindow(d): + (code, answer) = d.inputbox("New window name?", init="bash") + if code == d.DIALOG_OK: + commands.getoutput('screen -t %s' % answer) def default(d): d.msgbox("This has yet to be implemented") @@ -90,7 +103,7 @@ def main(): elif tag == "2": profile(d) elif tag == "3": - key(d) + newwindow(d) elif tag == "4": default(d) diff --git a/select-screen-profile b/select-screen-profile index 7692b94e..bfb14018 100755 --- a/select-screen-profile +++ b/select-screen-profile @@ -35,18 +35,28 @@ usage: select-screen-profiles [(-l|--list)][(-h|--help)][(-s|--set) PROFILE] EOT } +# Initialize variables BASE_DIR="/usr/share/screen-profiles" PROFILE_DIR="$BASE_DIR/profiles" +WINDOW_DIR="$BASE_DIR/windows" profile="" selected=-1 # Ensure that ~/.screenrc-profile is a symbolic link if [ -e "$HOME/.screenrc-profile" ]; then - if [ ! -L "$HOME/.screenrc-profile" ]; then - echo `gettext 'Error:'` $HOME/.screenrc-profile `gettext ' file exists, but is not a symlink'` - exit 1 - fi + if [ ! -L "$HOME/.screenrc-profile" ]; then + echo `gettext 'Error:'` $HOME/.screenrc-profile `gettext ' file exists, but is not a symlink'` + exit 1 + fi fi +# Ensure that ~/.screenrc-window is a symbolic link +if [ -e "$HOME/.screenrc-window" ]; then + if [ ! -L "$HOME/.screenrc-window" ]; then + echo `gettext 'Error:'` $HOME/.screenrc-window `gettext ' file exists, but is not a symlink'` + exit 1 + fi +fi + profiles=$(ls $PROFILE_DIR) @@ -81,12 +91,14 @@ prompt() { } listprofiles() { + # Display list of profiles, one per line for x in $profiles; do echo "$x" done } setprofile() { + # Apply a profile by name ($profile) or index ($selected) i=0 found=0 for x in $profiles; do @@ -95,20 +107,31 @@ setprofile() { if [ ! -e "$HOME/.screenrc" ]; then # If the user doesn't have a .screenrc, seed one echo "source ~/.screenrc-profile" > "$HOME/.screenrc" + echo "source ~/.screenrc-window" >> "$HOME/.screenrc" else # If the user does have a .screenrc, see if it has the - # source line - if ! grep -qs "source $HOME/.screenrc-profile" "$HOME/.screenrc"; then - # And if it's missing the source line, add it - # to the top - tmp=`mktemp "$HOME/.screenrc.XXXXXX"` - echo "source $HOME/.screenrc-profile" > "$tmp" - cat "$HOME/.screenrc" >> "$tmp" - mv -f "$tmp" "$HOME/.screenrc" - fi + # sources lines + if ! grep -qs "source $HOME/.screenrc-profile" "$HOME/.screenrc"; then + # And if it's missing the source line, add it + # to the top + tmp=`mktemp "$HOME/.screenrc.XXXXXX"` + echo "source $HOME/.screenrc-profile" > "$tmp" + cat "$HOME/.screenrc" >> "$tmp" + mv -f "$tmp" "$HOME/.screenrc" + fi + if ! grep -qs "source $HOME/.screenrc-window" "$HOME/.screenrc"; then + # And if it's missing the source line, add it + # to the top + tmp=`mktemp "$HOME/.screenrc.XXXXXX"` + echo "source $HOME/.screenrc-window" > "$tmp" + cat "$HOME/.screenrc" >> "$tmp" + mv -f "$tmp" "$HOME/.screenrc" + fi fi rm -f "$HOME/.screenrc-profile" + rm -f "$HOME/.screenrc-window" ln -s "$PROFILE_DIR/$x" "$HOME/.screenrc-profile" + ln -s "$WINDOW_DIR/default" "$HOME/.screenrc-window" found=1 fi done diff --git a/windows/default b/windows/default new file mode 100644 index 00000000..733692a6 --- /dev/null +++ b/windows/default @@ -0,0 +1,3 @@ +# Default windows +screen -t bash 1 +screen -t welcome 0 python /usr/share/screen-profiles/screen-profiles-helper.py From 567831d54613cf7fe784bdc65d374cf86d44d4a9 Mon Sep 17 00:00:00 2001 From: Nick Barcet Date: Sat, 20 Dec 2008 01:20:24 +0100 Subject: [PATCH 4/9] screen-profile-helper allows to install screen by default --- debian/changelog | 1 + debian/install | 4 +- screen-install | 35 +++++++++++ screen-launcher | 9 +++ screen-profiles-helper.py | 118 -------------------------------------- windows/default | 2 +- 6 files changed, 49 insertions(+), 120 deletions(-) create mode 100644 screen-install create mode 100644 screen-launcher delete mode 100644 screen-profiles-helper.py diff --git a/debian/changelog b/debian/changelog index cca97c8a..2a9e4179 100644 --- a/debian/changelog +++ b/debian/changelog @@ -8,6 +8,7 @@ screen-profiles (1.1-0ubuntu1) jaunty; urgency=low * Allow select-screen-profile to not run interactively * screen-profile-helper allows to create new windows * screen-profile-helper allows to select profiles + * screen-profile-helper allows to install screen by default [ Dustin Kirkland ] * created keybindings directory, moved keybindings there diff --git a/debian/install b/debian/install index f506ae65..5d8d2f5c 100644 --- a/debian/install +++ b/debian/install @@ -9,4 +9,6 @@ profiles/ubuntu.screenrc usr/share/screen-profiles/profiles keybindings/common usr/share/screen-profiles/keybindings windows/default usr/share/screen-profiles/windows select-screen-profile usr/bin -screen-profiles-helper.py usr/share/screen-profiles/ +screen-profiles-helper usr/bin +screen-install usr/share/screen-profiles/ +screen-launcher usr/share/screen-profiles/ diff --git a/screen-install b/screen-install new file mode 100644 index 00000000..0469f720 --- /dev/null +++ b/screen-install @@ -0,0 +1,35 @@ +#!/bin/bash + +LAUNCHER="$HOME/.screen-launcher" +BASHRC="$HOME/.bashrc" + +# We have to make sure screen is called last +pos=$(( $(grep -ns "source $LAUNCHER" "$BASHRC" | sed 's/:.*$//' | head -1) )) + +do=0 +if [ $pos -gt 0 ]; then + if [ $pos -lt $(( $(wc -l "$BASHRC" | sed "s/ .*$//") -2)) ]; then + # We have to reposition the line at the end + # First remove it + sed -ibak '/screen-launcher/d' "$BASHRC" + do=1 + fi +else + do=1 +fi + +# Add it at the end +if [ $do -eq 1 ]; then + echo "source $LAUNCHER" >> "$BASHRC" +fi + +# Ensure that ~/.screen-launcher is a symbolic link +if [ -e "$HOME/.screen-launcher" ]; then + if [ ! -L "$HOME/.screen-launcher" ]; then + echo `gettext 'Error:'` $HOME/.screen-launcher `gettext ' file exists, but is not a symlink'` + exit 1 + fi +else + ln -s /usr/share/screen-profiles/screen-launcher "$HOME/.screen-launcher" +fi + diff --git a/screen-launcher b/screen-launcher new file mode 100644 index 00000000..6a9e3812 --- /dev/null +++ b/screen-launcher @@ -0,0 +1,9 @@ +#!/bin/bash + +# Verify that we are correctly installed +bash /usr/share/screen-profiles/screen-install + +if [ "$TERM" != "screen" ]; then + screen -xRR + logout +fi diff --git a/screen-profiles-helper.py b/screen-profiles-helper.py deleted file mode 100644 index a7d936ec..00000000 --- a/screen-profiles-helper.py +++ /dev/null @@ -1,118 +0,0 @@ -#! /usr/bin/env python - -import sys, os, os.path, time, string, dialog, commands - -def ioctl_GWINSZ(fd): #### TABULATION FUNCTIONS - try: ### Discover terminal width - import fcntl, termios, struct, os - cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234')) - except: - return None - return cr - -def terminal_size(): ### decide on *some* terminal size - cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2) # try open fds - if not cr: # ...then ctty - try: - fd = os.open(os.ctermid(), os.O_RDONLY) - cr = ioctl_GWINSZ(fd) - os.close(fd) - except: - pass - if not cr: # env vars or finally defaults - try: - cr = (env['LINES'], env['COLUMNS']) - except: - cr = (25, 80) - return int(cr[1]-5), int(cr[0]-5) # reverse rows, cols - - -def handle_exit_code(d, code): - # d is supposed to be a Dialog instance - if code in (d.DIALOG_CANCEL, d.DIALOG_ESC): - if code == d.DIALOG_CANCEL: - msg = "You chose cancel. Do you want to " \ - "exit this program?" - else: - msg = "You pressed ESC. Do you want to " \ - "exit this program?" - # "No" or "ESC" will bring the user back to the demo. - # DIALOG_ERROR is propagated as an exception and caught in main(). - # So we only need to handle OK here. - if d.yesno(msg) == d.DIALOG_OK: - sys.exit(0) - return 0 - else: - return 1 # code is d.DIALOG_OK - -def menu_demo(d, size): - while 1: - (code, tag) = d.menu( - "Please chose an action", - width=size[0], - choices=[("1", "Display some basic help"), - ("2", "Change screen profile"), - ("3", "Create a new window"), - ("4", "Install screen by default at login") - ]) - if handle_exit_code(d, code): - break - return tag - -def help(d, size): - d.textbox("/usr/share/doc/screen-profiles/help.txt", width=size[0], height=size[1]) - -def profile(d): - list = [] - for choice in commands.getoutput('select-screen-profile -l').splitlines(): - if choice.startswith("ubuntu"): - el = (choice, "<-- recommended", 1) - list.append(el) - else: - el = (choice, "", 0) - list.append(el) - (code, tag) = d.radiolist("Which profile would you like to use?", width=65, choices=list) - if code == d.DIALOG_OK: - commands.getoutput('select-screen-profile --set %s' % tag) - d.msgbox("Please press F5 to apply profile") - -def newwindow(d): - (code, answer) = d.inputbox("New window name?", init="bash") - if code == d.DIALOG_OK: - commands.getoutput('screen -t %s' % answer) - -def default(d): - d.msgbox("This has yet to be implemented") - -def main(): - """This is the main loop of our screen helper. - - """ - size = terminal_size() - - try: - d = dialog.Dialog(dialog="dialog") - d.add_persistent_args(["--backtitle", "GNU Screen profiles helper"]) - - help(d, size) - - while True: - tag = menu_demo(d, size) - if tag == "1": - help (d, size) - elif tag == "2": - profile(d) - elif tag == "3": - newwindow(d) - elif tag == "4": - default(d) - - except dialog.error, exc_instance: - sys.stderr.write("Error:\n\n%s\n" % exc_instance.complete_message()) - sys.stderr.write("%s\n" % dialog.error) - sys.exit(1) - - sys.exit(0) - - -if __name__ == "__main__": main() diff --git a/windows/default b/windows/default index 733692a6..cab40b09 100644 --- a/windows/default +++ b/windows/default @@ -1,3 +1,3 @@ # Default windows screen -t bash 1 -screen -t welcome 0 python /usr/share/screen-profiles/screen-profiles-helper.py +screen -t welcome 0 screen-profiles-helper From 8a1192511c7c9c37bfbfa205eee70660c6761e8a Mon Sep 17 00:00:00 2001 From: Nick Barcet Date: Sat, 20 Dec 2008 01:21:18 +0100 Subject: [PATCH 5/9] re add screen-profile-helper --- screen-profiles-helper | 122 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100755 screen-profiles-helper diff --git a/screen-profiles-helper b/screen-profiles-helper new file mode 100755 index 00000000..b525f482 --- /dev/null +++ b/screen-profiles-helper @@ -0,0 +1,122 @@ +#! /usr/bin/env python + +import sys, os, os.path, time, string, dialog, commands + +def ioctl_GWINSZ(fd): #### TABULATION FUNCTIONS + try: ### Discover terminal width + import fcntl, termios, struct, os + cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234')) + except: + return None + return cr + +def terminal_size(): ### decide on *some* terminal size + cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2) # try open fds + if not cr: # ...then ctty + try: + fd = os.open(os.ctermid(), os.O_RDONLY) + cr = ioctl_GWINSZ(fd) + os.close(fd) + except: + pass + if not cr: # env vars or finally defaults + try: + cr = (env['LINES'], env['COLUMNS']) + except: + cr = (25, 80) + return int(cr[1]-5), int(cr[0]-5) # reverse rows, cols + + +def handle_exit_code(d, code): + # d is supposed to be a Dialog instance + if code in (d.DIALOG_CANCEL, d.DIALOG_ESC): + if code == d.DIALOG_CANCEL: + msg = "You chose cancel. Do you want to " \ + "exit this program?" + else: + msg = "You pressed ESC. Do you want to " \ + "exit this program?" + # "No" or "ESC" will bring the user back to the demo. + # DIALOG_ERROR is propagated as an exception and caught in main(). + # So we only need to handle OK here. + if d.yesno(msg) == d.DIALOG_OK: + sys.exit(0) + return 0 + else: + return 1 # code is d.DIALOG_OK + +def menu_demo(d, size): + while 1: + (code, tag) = d.menu( + "Please chose an action", + width=size[0], + choices=[("1", "Display some basic help"), + ("2", "Change screen profile"), + ("3", "Create a new window"), + ("4", "Install screen by default at login") + ]) + if handle_exit_code(d, code): + break + return tag + +def help(d, size): + d.textbox("/usr/share/doc/screen-profiles/help.txt", width=size[0], height=size[1]) + +def profile(d): + list = [] + for choice in commands.getoutput('select-screen-profile -l').splitlines(): + if choice.startswith("ubuntu"): + el = (choice, "<-- recommended", 1) + list.append(el) + else: + el = (choice, "", 0) + list.append(el) + (code, tag) = d.radiolist("Which profile would you like to use?", width=65, choices=list) + if code == d.DIALOG_OK: + commands.getoutput('select-screen-profile --set %s' % tag) + d.msgbox("Please press F5 to apply profile") + +def newwindow(d): + (code, answer) = d.inputbox("New window name?", init="bash") + if code == d.DIALOG_OK: + commands.getoutput('screen -t %s' % answer) + +def install(d): + out = commands.getoutput("bash /usr/share/screen-profiles/screen-install") + if out == "": + out = "Screen will be launched automatically next time you login." + + d.msgbox(out) + +def main(): + """This is the main loop of our screen helper. + + """ + size = terminal_size() + + try: + d = dialog.Dialog(dialog="dialog") + d.add_persistent_args(["--backtitle", "GNU Screen profiles helper"]) + + help(d, size) + + while True: + tag = menu_demo(d, size) + if tag == "1": + help (d, size) + elif tag == "2": + profile(d) + elif tag == "3": + newwindow(d) + elif tag == "4": + install(d) + + except dialog.error, exc_instance: + sys.stderr.write("Error:\n\n%s\n" % exc_instance.complete_message()) + sys.stderr.write("%s\n" % dialog.error) + sys.exit(1) + + sys.exit(0) + + +if __name__ == "__main__": main() From 04f783221649187afcb4618dd90fe34f9942e25b Mon Sep 17 00:00:00 2001 From: Nick Barcet Date: Sun, 21 Dec 2008 06:21:35 +0100 Subject: [PATCH 6/9] Now uses python-newt instead of python-dialog --- debian/changelog | 1 + doc/help.txt | 6 +- screen-profiles-helper | 192 +++++++++++++++++++++++++---------------- 3 files changed, 124 insertions(+), 75 deletions(-) diff --git a/debian/changelog b/debian/changelog index 2a9e4179..ae52ce74 100644 --- a/debian/changelog +++ b/debian/changelog @@ -9,6 +9,7 @@ screen-profiles (1.1-0ubuntu1) jaunty; urgency=low * screen-profile-helper allows to create new windows * screen-profile-helper allows to select profiles * screen-profile-helper allows to install screen by default + * Now uses python-newt instead of python-dialog [ Dustin Kirkland ] * created keybindings directory, moved keybindings there diff --git a/doc/help.txt b/doc/help.txt index 08b4d0bf..3d52bfd1 100644 --- a/doc/help.txt +++ b/doc/help.txt @@ -1,6 +1,6 @@ - ******************************************** - ** Welcome to the screen powered terminal ** - ******************************************** +Welcome to GNU Screen Profiles +------------------------------ + The main benefits of the screen program is that your session can have multiple windows and keep context between multiple logins. You will also notice the task bar at the bottom that informs you of various system diff --git a/screen-profiles-helper b/screen-profiles-helper index b525f482..393be20f 100755 --- a/screen-profiles-helper +++ b/screen-profiles-helper @@ -1,6 +1,26 @@ #! /usr/bin/env python +# +# GNU screen-profiles-helper +# Copyright (C) 2008 Canonical Ltd. +# +# Authors: Nick Barcet +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -import sys, os, os.path, time, string, dialog, commands +import sys, os, os.path, time, string, commands +from snack import * def ioctl_GWINSZ(fd): #### TABULATION FUNCTIONS try: ### Discover terminal width @@ -26,96 +46,124 @@ def terminal_size(): ### decide on *some* terminal size cr = (25, 80) return int(cr[1]-5), int(cr[0]-5) # reverse rows, cols - -def handle_exit_code(d, code): - # d is supposed to be a Dialog instance - if code in (d.DIALOG_CANCEL, d.DIALOG_ESC): - if code == d.DIALOG_CANCEL: - msg = "You chose cancel. Do you want to " \ - "exit this program?" - else: - msg = "You pressed ESC. Do you want to " \ - "exit this program?" - # "No" or "ESC" will bring the user back to the demo. - # DIALOG_ERROR is propagated as an exception and caught in main(). - # So we only need to handle OK here. - if d.yesno(msg) == d.DIALOG_OK: - sys.exit(0) +def menu(screen, size): + li = Listbox(height = 4, width = 60, returnExit = 1) + li.append("Help", 1) + li.append("Change screen profile", 2) + li.append("Create new window", 3) + li.append("Install screen by default at login", 4) + bb = ButtonBar(screen, (("Ok", "ok"), ("Exit", "exit")), compact = 1) + + g = GridForm(screen, "GNU Screen Profiles Menu", 1, 2) + g.add(li, 0, 0, padding=(4,2,4,2)) + g.add(bb, 0, 1, padding=(1,1,0,0)) + + if bb.buttonPressed(g.runOnce()) == "exit": return 0 else: - return 1 # code is d.DIALOG_OK + return li.current() -def menu_demo(d, size): - while 1: - (code, tag) = d.menu( - "Please chose an action", - width=size[0], - choices=[("1", "Display some basic help"), - ("2", "Change screen profile"), - ("3", "Create a new window"), - ("4", "Install screen by default at login") - ]) - if handle_exit_code(d, code): - break - return tag +def messagebox(screen, width, height, title, text, \ + scroll=0, \ + buttons=(("Ok", "ok"),("Cancel", "cancel")) ): + + t = Textbox(width, height, text, scroll=scroll ) + bb = ButtonBar(screen, buttons, compact = 1) + g = GridForm(screen, title, 1, 2) + g.add(t, 0, 0, padding=(0,0,0,0)) + g.add(bb, 0, 1, padding=(1,1,0,0)) + + return bb.buttonPressed(g.runOnce()) -def help(d, size): - d.textbox("/usr/share/doc/screen-profiles/help.txt", width=size[0], height=size[1]) - -def profile(d): - list = [] +def help(screen, size): + f=file('/usr/share/doc/screen-profiles/help.txt') + text=f.read() + f.close() + + button = messagebox(screen, 76, 19, "GNU Screen Profiles Help", text, \ + scroll=1, buttons=(("Menu", "menu"), ("Exit", "exit")) ) + + if button == "exit": + return 0 + else: + return 100 + +def profile(screen, size): + li = Listbox(height = 6, width = 60, returnExit = 1) + for choice in commands.getoutput('select-screen-profile -l').splitlines(): if choice.startswith("ubuntu"): - el = (choice, "<-- recommended", 1) - list.append(el) + li.append(choice+" <-- recommended", choice) + li.setCurrent(choice) else: - el = (choice, "", 0) - list.append(el) - (code, tag) = d.radiolist("Which profile would you like to use?", width=65, choices=list) - if code == d.DIALOG_OK: - commands.getoutput('select-screen-profile --set %s' % tag) - d.msgbox("Please press F5 to apply profile") + li.append(choice, choice) + + bb = ButtonBar(screen, (("Apply", "apply"), ("Cancel", "cancel")), compact = 1) + + g = GridForm(screen, "Which profile would you like to use?", 1, 2) + g.add(li, 0, 0, padding=(4,2,4,2)) + g.add(bb, 0, 1, padding=(1,1,0,0)) + + if bb.buttonPressed(g.runOnce()) != "cancel": + commands.getoutput('select-screen-profile --set %s' % li.current()) + button = messagebox(screen, 60, 2, "Message", "Press F5 to apply the new profile", \ + buttons=(("Ok","ok"), ("Exit", "exit")) ) + if button == "exit": + return 0 + + return 100 -def newwindow(d): - (code, answer) = d.inputbox("New window name?", init="bash") - if code == d.DIALOG_OK: - commands.getoutput('screen -t %s' % answer) +def newwindow(screen, size): + title=Entry(8, text="bash", returnExit=1) + titlel=Label("Title: ") + command=Entry(20, text="/bin/bash", returnExit=1) + commandl=Label("Command: ") + bb = ButtonBar(screen, (("Create", "create"), ("Cancel", "cancel")), compact = 1) + g = GridForm(screen, "Create new window:", 2, 3, ) + g.add(titlel, 0, 0, anchorLeft=1,padding=(0,1,0,1)) + g.add(title, 1, 0, anchorLeft=1) + g.add(commandl, 0, 1, anchorLeft=1,padding=(0,0,0,1)) + g.add(command, 1, 1, anchorLeft=1) + g.add(bb, 0, 2, padding=(1,1,0,0)) + + if bb.buttonPressed(g.runOnce()) != "cancel": + commands.getoutput('screen -t %s %s' % (title.value(), command.value()) ) + + return 100 -def install(d): +def install(screen, size): out = commands.getoutput("bash /usr/share/screen-profiles/screen-install") if out == "": out = "Screen will be launched automatically next time you login." - d.msgbox(out) + button = messagebox(screen, 60, 2, "Message", out, \ + buttons=(("Ok","ok"), ("Exit", "exit")) ) + if button == "exit": + return 0 + + return 100 def main(): """This is the main loop of our screen helper. - """ size = terminal_size() + screen = SnackScreen() + screen.drawRootText(1,0,"== GNU Screen Profiles Helper ==") + screen.pushHelpLine("/ between elements | Validates") + tag = help(screen, size) + + while tag > 0 : + tag = menu(screen, size) + if tag == 1: + tag = help(screen, size) + elif tag == 2: + tag = profile(screen, size) + elif tag == 3: + tag = newwindow(screen, size) + elif tag == 4: + tag = install(screen, size) - try: - d = dialog.Dialog(dialog="dialog") - d.add_persistent_args(["--backtitle", "GNU Screen profiles helper"]) - - help(d, size) - - while True: - tag = menu_demo(d, size) - if tag == "1": - help (d, size) - elif tag == "2": - profile(d) - elif tag == "3": - newwindow(d) - elif tag == "4": - install(d) - - except dialog.error, exc_instance: - sys.stderr.write("Error:\n\n%s\n" % exc_instance.complete_message()) - sys.stderr.write("%s\n" % dialog.error) - sys.exit(1) - + screen.finish() sys.exit(0) From f8ad0a788802f8202fdf6ec79b43852275df7476 Mon Sep 17 00:00:00 2001 From: Nick Barcet Date: Sun, 21 Dec 2008 06:22:49 +0100 Subject: [PATCH 7/9] Update dependency --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index e2823af1..c4d7d9b8 100644 --- a/debian/control +++ b/debian/control @@ -9,7 +9,7 @@ Vcs-Bzr: http://bazaar.launchpad.net/~kirkland/screen-profiles/main Package: screen-profiles Architecture: all -Depends: debconf (>= 0.5) | debconf-2.0, screen, gettext-base, debianutils, python-dialog +Depends: debconf (>= 0.5) | debconf-2.0, screen, gettext-base, debianutils, python-newt Recommends: update-notifier-common Suggests: bc Description: a set of useful profiles and a profile-switcher for GNU screen From 4a0769261d6f00dcd123acfbfe9033c93bbd55bf Mon Sep 17 00:00:00 2001 From: Nick Barcet Date: Sun, 21 Dec 2008 15:52:09 +0100 Subject: [PATCH 8/9] Add framework for usefull windows creation --- debian/changelog | 1 + screen-profiles-helper | 42 +++++++++++++++++++++++++++++++++++------- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/debian/changelog b/debian/changelog index ae52ce74..45f9b858 100644 --- a/debian/changelog +++ b/debian/changelog @@ -10,6 +10,7 @@ screen-profiles (1.1-0ubuntu1) jaunty; urgency=low * screen-profile-helper allows to select profiles * screen-profile-helper allows to install screen by default * Now uses python-newt instead of python-dialog + * Add framework for usefull windows creation [ Dustin Kirkland ] * created keybindings directory, moved keybindings there diff --git a/screen-profiles-helper b/screen-profiles-helper index 393be20f..60eef7eb 100755 --- a/screen-profiles-helper +++ b/screen-profiles-helper @@ -22,6 +22,12 @@ import sys, os, os.path, time, string, commands from snack import * +# Command presets for windows creation +cmd=( ("System activity", "top", "top"), + ("System log", "log", "watch -n 10 tail -n 5 /var/log/syslog /var/log/auth.log /var/log/dmesg"), + ("Disk and ram usage", "mem", 'watch -n 30 "df -h; echo ""; free -mt"')) + + def ioctl_GWINSZ(fd): #### TABULATION FUNCTIONS try: ### Discover terminal width import fcntl, termios, struct, os @@ -50,7 +56,7 @@ def menu(screen, size): li = Listbox(height = 4, width = 60, returnExit = 1) li.append("Help", 1) li.append("Change screen profile", 2) - li.append("Create new window", 3) + li.append("Create new window(s)", 3) li.append("Install screen by default at login", 4) bb = ButtonBar(screen, (("Ok", "ok"), ("Exit", "exit")), compact = 1) @@ -106,7 +112,7 @@ def profile(screen, size): if bb.buttonPressed(g.runOnce()) != "cancel": commands.getoutput('select-screen-profile --set %s' % li.current()) - button = messagebox(screen, 60, 2, "Message", "Press F5 to apply the new profile", \ + button = messagebox(screen, 60, 2, "Message", "Press F5 to apply the new profile", \ buttons=(("Ok","ok"), ("Exit", "exit")) ) if button == "exit": return 0 @@ -118,16 +124,38 @@ def newwindow(screen, size): titlel=Label("Title: ") command=Entry(20, text="/bin/bash", returnExit=1) commandl=Label("Command: ") + + rl=Label("Presets: ") + if len(cmd) > 10: + scroll=1 + size=10 + else: + scroll=0 + size = len(cmd) + + r=CheckboxTree(size, scroll=scroll) + count=0 + for cur in cmd: + r.append(cur[0], count) + count=count+1 + bb = ButtonBar(screen, (("Create", "create"), ("Cancel", "cancel")), compact = 1) - g = GridForm(screen, "Create new window:", 2, 3, ) - g.add(titlel, 0, 0, anchorLeft=1,padding=(0,1,0,1)) + g = GridForm(screen, "Create new window(s):", 2, 4 ) + g.add(titlel, 0, 0, anchorLeft=1,padding=(4,1,0,1)) g.add(title, 1, 0, anchorLeft=1) - g.add(commandl, 0, 1, anchorLeft=1,padding=(0,0,0,1)) + g.add(commandl, 0, 1, anchorLeft=1, anchorTop=1,padding=(4,0,0,1)) g.add(command, 1, 1, anchorLeft=1) - g.add(bb, 0, 2, padding=(1,1,0,0)) + g.add(rl, 0, 2, anchorLeft=1,padding=(4,0,0,1)) + g.add(r, 1, 2) + g.add(bb, 1, 3, padding=(4,1,0,0)) if bb.buttonPressed(g.runOnce()) != "cancel": - commands.getoutput('screen -t %s %s' % (title.value(), command.value()) ) + sel=r.getSelection() + if sel: + for s in sel: + commands.getoutput('screen -t %s %s' % (cmd[s][1], cmd[s][2]) ) + else: + commands.getoutput('screen -t %s %s' % (title.value(), command.value()) ) return 100 From d03ab255a4aa42a3141015b48b42b45a436de0bc Mon Sep 17 00:00:00 2001 From: Nick Barcet Date: Sun, 21 Dec 2008 21:24:02 +0100 Subject: [PATCH 9/9] help adjustments --- doc/help.txt | 3 +-- keybindings/common | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/doc/help.txt b/doc/help.txt index 3d52bfd1..d535ac90 100644 --- a/doc/help.txt +++ b/doc/help.txt @@ -1,6 +1,5 @@ Welcome to GNU Screen Profiles ------------------------------ - The main benefits of the screen program is that your session can have multiple windows and keep context between multiple logins. You will also notice the task bar at the bottom that informs you of various system @@ -19,6 +18,6 @@ C-pgdown Goto next window | F4 Create new window C-shift-del Detach and logout | F6 Close current window ------------------------------------------------------------------- -Note that these bindings have been tested for xterm type terminal such as +Note that these bindings have been tested for xterm type terminals such as gnome-terminal, but may need some adjustments elsewhere. diff --git a/keybindings/common b/keybindings/common index f1fe27f9..7be678c5 100644 --- a/keybindings/common +++ b/keybindings/common @@ -37,7 +37,7 @@ bindkey -k k4 process n # F4 | Create new window bindkey -k k6 kill # F6 | Close window # Maps for help -bindkey -k k1 screen -t help 0 less /usr/share/doc/screen-profiles/help.txt # F1 | Basic help (this) +bindkey -k k1 screen -t help 0 screen-profiles-helper # F1 | Basic help (this) bindkey -k k2 help # F2 | Advanced help # Reload