commit
7b2650b646
19 changed files with 1905 additions and 0 deletions
@ -0,0 +1,57 @@ |
|||
Contributing |
|||
============ |
|||
|
|||
All kinds of contributions to Mons are greatly appreciated. For someone |
|||
unfamiliar with the code base, the most efficient way to contribute is usually |
|||
to submit a [feature request](#feature-requests) or [bug report](#bug-reports). |
|||
If you want to dive into the source code, you can submit a [patch](#patches) as |
|||
well, either working on your own ideas or [existing issues][issues]. |
|||
|
|||
Feature Requests |
|||
---------------- |
|||
|
|||
Do you have an idea for an awesome new feature for Mons? Please [submit a |
|||
feature request][issue]. It's great to hear about new ideas. |
|||
|
|||
If you are inclined to do so, you're welcome to [fork][fork] Mons, work on |
|||
implementing the feature yourself, and submit a patch. In this case, it's |
|||
*highly recommended* that you first [open an issue][issue] describing your |
|||
enhancement to get early feedback on the new feature that you are implementing. |
|||
This will help avoid wasted efforts and ensure that your work is incorporated |
|||
into the code base. |
|||
|
|||
Bug Reports |
|||
----------- |
|||
|
|||
Did something go wrong with Mons? Sorry about that! Bug reports are greatly |
|||
appreciated! |
|||
|
|||
When you [submit a bug report][issue], please include relevant information such |
|||
as Mons version, operating system, configuration file, error messages, and |
|||
steps to reproduce the bug. The more details you can include, the easier it is |
|||
to find and fix the bug. |
|||
|
|||
Patches |
|||
------- |
|||
|
|||
If there are [open issues][issues], you're more than welcome to work on those - |
|||
this is probably the best way to contribute to Mons. If you have your own |
|||
ideas, that's great too! In that case, before working on substantial changes to |
|||
the code base, it is *highly recommended* that you first [open an issue][issue] |
|||
describing what you intend to work on. |
|||
|
|||
**Patches are generally submitted as pull requests.** Patches are also |
|||
[accepted over email][email]. |
|||
|
|||
The version history should be clean, and commit messages should be descriptive |
|||
and [properly formatted][commit-messages]. |
|||
|
|||
--- |
|||
|
|||
If you have any questions about anything, feel free to [ask][email]! |
|||
|
|||
[issue]: https://github.com/ventto/mons/issues/new |
|||
[issues]: https://github.com/ventto/mons/issues |
|||
[fork]: https://github.com/ventto/mons/fork |
|||
[email]: mailto:thomas.venries@gmail.com |
|||
[commit-messages]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html |
@ -0,0 +1,20 @@ |
|||
The MIT License (MIT) |
|||
|
|||
Copyright (c) 2016-2017 Thomas "Ventto" Venriès <thomas.venries@gmail.com> |
|||
|
|||
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. |
@ -0,0 +1,37 @@ |
|||
PKGNAME = mons |
|||
PKGDESC = POSIX Shell script to quickly manage 2-monitors display. |
|||
|
|||
LICENSEDIR = $(DESTDIR)/usr/share/licenses/$(PKGNAME) |
|||
MANDIR = $(DESTDIR)/usr/share/man/man1 |
|||
BINDIR = $(DESTDIR)/usr/bin |
|||
LIBDIR = $(DESTDIR)/usr/lib/libshlist |
|||
LIB = libshlist/liblist.sh |
|||
|
|||
install: |
|||
@if ! [ -r "$(LIB)" ]; then \
|
|||
echo "$(LIB): missing file"; \
|
|||
exit 1; \
|
|||
fi |
|||
help2man -N -n "$(PKGDESC)" -h -h -v -v ./$(PKGNAME) | gzip - > $(PKGNAME).1.gz |
|||
@if ! [ -r "$(PKGNAME).1.gz" ]; then \
|
|||
echo "$(PKGNAME).1.gz: missing manpage"; \
|
|||
exit 1; \
|
|||
fi |
|||
mkdir -p $(MANDIR) |
|||
mkdir -p $(LICENSEDIR) |
|||
mkdir -p $(LIBDIR) |
|||
mkdir -p $(BINDIR) |
|||
chmod 644 $(PKGNAME).1.gz |
|||
chmod 644 LICENSE |
|||
chmod 644 $(LIB) |
|||
chmod 755 mons |
|||
cp $(PKGNAME).1.gz $(MANDIR)/$(PKGNAME).1.gz |
|||
cp LICENSE $(LICENSEDIR)/LICENSE |
|||
cp $(LIB) $(LIBDIR)/liblist.sh |
|||
cp mons $(BINDIR)/mons |
|||
|
|||
uninstall: |
|||
$(RM) -r $(LIBDIR) |
|||
$(RM) $(BINDIR)/mons |
|||
|
|||
.PHONY: install uninstall |
@ -0,0 +1,200 @@ |
|||
Mons |
|||
=================== |
|||
[](https://github.com/Ventto/mons/blob/master/LICENSE) |
|||
[](https://www.x.org/archive/X11R7.5/doc/man/man1/xrandr.1.html) |
|||
[](https://aur.archlinux.org/packages/mons/) |
|||
|
|||
|
|||
|
|||
*"Mons is a Shell script to quickly manage 2-monitors display using xrandr."* |
|||
|
|||
## Perks |
|||
|
|||
* [x] **No requirement**: POSIX-compliant (minimal: *xorg-xrandr*) |
|||
* [x] **Useful**: Perfectly fit for laptops, quick and daily use |
|||
* [x] **Well known**: Laptop mode, projector mode, duplicate, mirror and extend |
|||
* [x] **More**: Select one or two monitors over several others |
|||
* [x] **Extra**: Cycle through every mode with only one shortcut |
|||
* [x] **Auto**: Deamon mode to automatically reset display |
|||
|
|||
# Installation |
|||
|
|||
* Package (AUR) |
|||
|
|||
``` |
|||
$ pacaur -S mons |
|||
``` |
|||
|
|||
* Manual |
|||
|
|||
``` |
|||
$ git clone --recursive https://github.com/Ventto/mons.git |
|||
$ cd mons |
|||
$ sudo make install |
|||
``` |
|||
> Note: `--recursive` is needed for git submodule |
|||
|
|||
# Usage |
|||
|
|||
``` |
|||
Without argument, it prints connected monitors list with their names and ids. |
|||
Options are exclusive and can be used in conjunction with extra options. |
|||
|
|||
Information: |
|||
-h Prints this help and exits. |
|||
-v Prints version and exits. |
|||
|
|||
Two monitors: |
|||
-o Primary monitor only. |
|||
-s Second monitor only. |
|||
-d Duplicates the primary monitor. |
|||
-m Mirrors the primary monitor. |
|||
-e <side> |
|||
Extends the primary monitor to the selected side |
|||
[ top | left | right | bottom ]. |
|||
-n <side> |
|||
This mode selects the previous ones, one after another. The argument |
|||
sets the side for the extend mode. |
|||
|
|||
More monitors: |
|||
-O <mon> |
|||
Only enables the monitor with a specified id. |
|||
-S <mon1>,<mon2>:<pos> |
|||
Only enables two monitors with specified ids. The specified position |
|||
places the second monitor on the right (R) or at the top (T). |
|||
|
|||
Extra (in-conjunction options): |
|||
--dpi <dpi> |
|||
Set the DPI, a strictly positive value within the range [0 ; 27432]. |
|||
--primary <mon_name> |
|||
Select a connected monitor as the primary output. Run the script |
|||
without argument to print monitors information, the names are in the |
|||
second column between ids and status. The primary monitor is marked |
|||
by an asterisk. |
|||
|
|||
Daemon mode: |
|||
-a Performs an automatic display if it detects only one monitor. |
|||
``` |
|||
|
|||
# Examples |
|||
|
|||
## Two monitors |
|||
|
|||
Displays monitor list: |
|||
|
|||
``` |
|||
$ mons |
|||
0: LVDS-1 (enabled) |
|||
5: VGA-1 |
|||
``` |
|||
|
|||
You have an enabled one, you want to extends the second one on the right: |
|||
|
|||
``` |
|||
$ mons -e right |
|||
``` |
|||
|
|||
You want to only display the second one: |
|||
|
|||
``` |
|||
$ mons -s |
|||
``` |
|||
|
|||
With the `-n` option, go through every 2-mons mode consecutively: |
|||
|
|||
1. Primary monitor only |
|||
1. Second monitor only |
|||
1. Extend mode whose the side is set with `-n <side>` |
|||
1. Mirror |
|||
1. Duplicate |
|||
|
|||
This mode is useful if you want to switch to every mode with only one shortcut. |
|||
|
|||
 |
|||
|
|||
``` |
|||
# Now in 'Second monitor mode' |
|||
$ mons -n right # -> 'Extend mode' |
|||
# Now in 'Extend mode' |
|||
$ mons -n right # -> 'Mirror mode' |
|||
``` |
|||
|
|||
## Three monitors (selection mode) |
|||
|
|||
|
|||
Displays monitor list: |
|||
|
|||
``` |
|||
$ mons |
|||
Monitors: 3 |
|||
Mode: Selection |
|||
0:* LVDS-1 (enabled) |
|||
1: DP-1 (enabled) |
|||
5: VGA-1 |
|||
``` |
|||
|
|||
You may need to display only the third one: |
|||
|
|||
``` |
|||
$ mons -O 5 |
|||
``` |
|||
|
|||
You may need to display the first and the third one on the right: |
|||
|
|||
``` |
|||
$ mons -S 0,5:R |
|||
``` |
|||
|
|||
Like above but you want to inverse the placement: |
|||
|
|||
``` |
|||
$ mons -S 5,0:R |
|||
``` |
|||
|
|||
## DPI value |
|||
|
|||
You might want to switch mode and set the DPI value. |
|||
Use the `--dpi <dpi>` option in conjunction with all others options. |
|||
|
|||
``` |
|||
$ mons [OPTIONS] --dpi <dpi> |
|||
``` |
|||
|
|||
## Primary monitor |
|||
|
|||
You might choose one of your monitors as the main one. |
|||
You can use the `--primary <mon_name>` option alone or in conjunction with all |
|||
others options. |
|||
`<mon_name>` refers to the monitor name that appears in the list of connected |
|||
monitors (ex: `LVDS-1` or `VGA-1`): |
|||
|
|||
``` |
|||
$ mons |
|||
Monitors: 3 |
|||
Mode: Primary |
|||
0:* LVDS-1 (enabled) |
|||
5: VGA-1 |
|||
``` |
|||
|
|||
The '*' character means that the monitor is the primary one: |
|||
|
|||
``` |
|||
$ mons --primary VGA-1 |
|||
Monitors: 3 |
|||
Mode: Primary |
|||
0: LVDS-1 (enabled) |
|||
5:* VGA-1 |
|||
``` |
|||
|
|||
## Daemon mode |
|||
|
|||
Especially for laptops, after unplugging the additional monitors, it might be |
|||
convenient to reset automatically the display for the remaining one. |
|||
|
|||
Run *mons* in background as follow: |
|||
|
|||
``` |
|||
$ nohup mons -a > /dev/null 2>&1 & (all shells) |
|||
$ mons -a &! (zsh) |
|||
$ mons -a &; disown (bash) |
|||
``` |
@ -0,0 +1,19 @@ |
|||
/* |
|||
|
|||
!libshlist |
|||
|
|||
!img |
|||
img/* |
|||
!img/raw-body.png |
|||
|
|||
!test |
|||
test/* |
|||
!test/*.sh |
|||
|
|||
!mons |
|||
!CONTRIBUTING.md |
|||
!LICENSE |
|||
!Makefile |
|||
!README.md |
|||
!.gitignore |
|||
!.gitmodules |
@ -0,0 +1,3 @@ |
|||
[submodule "libshlist"] |
|||
path = libshlist |
|||
url = https://github.com/Ventto/libshlist.git |
After Width: | Height: | Size: 9.8 KiB |
@ -0,0 +1,20 @@ |
|||
The MIT License (MIT) |
|||
|
|||
Copyright (c) 2017-2018 Thomas "Ventto" Venriès <thomas.venries@gmail.com> |
|||
|
|||
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. |
@ -0,0 +1,111 @@ |
|||
POSIX Shell List |
|||
================ |
|||
|
|||
[](https://github.com/Ventto/posix-shell-list/blob/master/LICENSE) |
|||
|
|||
*"This is a POSIX Shell list implementation."* |
|||
|
|||
## Perks |
|||
|
|||
* [x] **No requirement**: POSIX-compliant |
|||
* [x] **Lightweight**: ~100 lines |
|||
* [x] **Extra**: Additional functions to fit your needs |
|||
* [x] **Useful**: No internal independency |
|||
* [x] **Both**: Safe and unsafe (passing argument by reference) versions |
|||
|
|||
# Installation |
|||
|
|||
* Download it: |
|||
|
|||
```bash |
|||
$ wget https://raw.githubusercontent.com/Ventto/posix-shell-list/master/liblist.sh |
|||
``` |
|||
|
|||
* Source the library for including the functions into your Shell script: |
|||
|
|||
```bash |
|||
. liblist.sh (or) |
|||
. liblist_unsafe.sh |
|||
``` |
|||
|
|||
* Each function is independent. So you can copy some functions into your |
|||
script without sourcing |
|||
|
|||
# Functions |
|||
|
|||
The whole function documentation is in the following library scripts: |
|||
|
|||
* `liblist.sh`: the variable assignation is required for conserving changes |
|||
* `liblist_unsafe.sh`: uses `eval` special shell builtin for passing argument |
|||
by reference and set the list variable |
|||
|
|||
The following list enumerates all available functions: |
|||
|
|||
``` |
|||
SAFE | UNSAFE |
|||
____________________________________|_______________________________ |
|||
list <elt> <elt> ... | list <elt> <elt> ... |
|||
list_back <lst> | list_back <lst> |
|||
list_contains <elt> <lst> | list_contains <lst> <elt> |
|||
list_count <elt> <lst> | list_count <lst> <elt> |
|||
list_empty <lst> | list_empty <lst> |
|||
list_erase <elt> <lst> | list_erase <lst> <elt> |
|||
list_erase_from <index> <lst> | list_erase_from <lst> <index> |
|||
list_erase_range <from> <to> <lst> | list_erase_range <lst> <from> <to> |
|||
list_eraseat <index> <lst> | list_eraseat <lst> <index> |
|||
list_extract <from> <to> <lst> | list_extract <lst> <from> <to> |
|||
list_front <lst> | list_front <lst> |
|||
list_get <index> <lst> | list_get <lst> <index> |
|||
list_indexof <elt> <lst> | list_indexof <lst> <elt> |
|||
list_insert <elt> <index> <lst> | list_insert <lst> <elt> <index> |
|||
list_maps <func> <lst> | list_maps <lst> <func> |
|||
list_pop_back <lst> | list_pop_back <lst> |
|||
list_pop_front <lst> | list_pop_front <lst> |
|||
list_push_back <elt> <lst> | list_push_back <lst> <elt> |
|||
list_push_front <elt> <lst> | list_push_front <lst> <elt> |
|||
list_remove <elt> <lst> | list_remove <lst> <elt> |
|||
list_replace <new> <old> <lst> | list_replace <lst> <new> <old> |
|||
list_reverse <lst> | list_reverse <lst> |
|||
list_set <elt> <index> <lst> | list_set <lst> <elt> <index> |
|||
list_size <lst> | list_size <lst> |
|||
list_sort <lst> | list_sort <lst> |
|||
list_sort_reverse <lst> | list_sort_reverse <lst> |
|||
``` |
|||
|
|||
# Example |
|||
|
|||
Scripts in `test/` offer an exhaustive usage of both libraries. |
|||
|
|||
* Quick start (safe version): |
|||
|
|||
```bash |
|||
lst="$(list 'A' 'B' 'C')" |
|||
lst="$(list_sort "$lst")" # { C, B, A } |
|||
|
|||
if list_empty "$lst"; then |
|||
echo 'The list is empty.' |
|||
fi |
|||
|
|||
index="$(list_indexof 'D' "$lst")" # '', empty string |
|||
|
|||
if [ "$?" -ne 0 ]; then |
|||
echo 'Element not found.' |
|||
fi |
|||
``` |
|||
|
|||
* Quick start (unsafe version): |
|||
|
|||
```bash |
|||
lst="$(list 'A' 'B' 'C')" |
|||
list_sort lst # { C, B, A } |
|||
|
|||
if list_empty lst; then |
|||
echo 'The list is empty.' |
|||
fi |
|||
|
|||
index="$(list_indexof lst 'D')" # '', empty string |
|||
|
|||
if [ "$?" -ne 0 ]; then |
|||
echo 'Element not found.' |
|||
fi |
|||
``` |
@ -0,0 +1 @@ |
|||
gitdir: ../.git/modules/libshlist |
@ -0,0 +1,271 @@ |
|||
#!/bin/sh |
|||
# |
|||
# The MIT License (MIT) |
|||
# |
|||
# Copyright (c) 2017-2018 Thomas "Ventto" Venriès <thomas.venries@gmail.com> |
|||
# |
|||
# 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. |
|||
|
|||
## |
|||
# @brief Return a list from argument strings |
|||
# @usage list <elt> <elt> ... |
|||
# @print The created list |
|||
# |
|||
list () { |
|||
for e; do [ -n "$e" ] && echo "$e"; done |
|||
} |
|||
|
|||
## |
|||
# @brief Prints the number of elements in the list |
|||
# @usage list_size <lst> |
|||
# @print The size of the list as positive integer |
|||
# |
|||
list_size () { |
|||
if [ -z "$1" ]; then echo '0'; else echo "$@" | wc -l; fi |
|||
} |
|||
|
|||
## |
|||
# @brief Returns whether the list is empty(1) or not(0) |
|||
# @usage list_empty <lst> |
|||
# @return The exit code of the command |
|||
# |
|||
list_empty () { |
|||
test -z "$1" |
|||
} |
|||
|
|||
## |
|||
# @brief Adds a new element at the beginning of the list |
|||
# @usage list_push_front <elt> <lst> |
|||
# @print The list result |
|||
# |
|||
list_push_front () { |
|||
test "$#" -ne 2 && return 1 |
|||
if [ "$2" = '' ]; then echo "$1"; else printf '%s\n%s' "$1" "$2"; fi |
|||
} |
|||
|
|||
## |
|||
# @brief Adds a new element at the end of the list |
|||
# @usage list_push_back <elt> <lst> |
|||
# @print The list result |
|||
# |
|||
list_push_back () { |
|||
test "$#" -ne 2 && return 1 |
|||
if [ "$2" = '' ]; then echo "$1"; else printf '%s\n%s' "$2" "$1"; fi |
|||
} |
|||
|
|||
## |
|||
# @brief Inserts new elements in the list before a specified position |
|||
# @usage list_insert <elt> <index> <lst> |
|||
# @print The list result |
|||
# |
|||
list_insert () { |
|||
test "$#" -ne 3 && return 1 |
|||
i="$2"; [ "$i" != '$' ] && i=$((i+1)); echo "$3" | sed "${i}i${1}" |
|||
} |
|||
|
|||
## |
|||
# @brief Modifies an element from the list at a specified position |
|||
# @usage list_set <elt> <index> <lst> |
|||
# @print The list result |
|||
# |
|||
list_set () { |
|||
test "$#" -ne 3 && return 1 |
|||
i="$2"; i=$((i+1)); echo "$3" | sed -e "${i}s/.*/$1/" |
|||
} |
|||
|
|||
## |
|||
# @brief Extracts a range of elements from the list between two specified |
|||
# positions |
|||
# @usage list_extract <from_index> <to_index> <lst> |
|||
# @print The list result |
|||
# |
|||
list_extract () { |
|||
test "$#" -ne 3 && return 1 |
|||
i="$1"; j="$2"; i=$((i+1)); j=$((j+1)); echo "$3" | sed -n "${i},${j}p" |
|||
} |
|||
|
|||
## |
|||
# @brief Replaces all elements from the list with a specified element |
|||
# @usage list_replace <new_elt> <old_elt> <lst> |
|||
# @print The list result |
|||
# |
|||
list_replace () { |
|||
test "$#" -ne 3 && return 1; echo "$3" | sed -e "s/^$1$/$2/g" |
|||
} |
|||
|
|||
## |
|||
# @brief Prints the element at a specified position |
|||
# @usage list_get <index> <lst> |
|||
# @print The element found |
|||
# |
|||
list_get () { |
|||
test "$#" -ne 2 && return 1; i="$1"; i=$((i+1)); echo "$2" | sed -n "${i}p" |
|||
} |
|||
|
|||
## |
|||
# @brief Prints the head of the list |
|||
# @usage list_front <lst> |
|||
# @print The element found |
|||
# |
|||
list_front () { |
|||
test "$#" -ne 1 && return 1; echo "$@" | sed -n '1p' |
|||
} |
|||
|
|||
## |
|||
# @brief Prints the queue of the list |
|||
# @usage list_back <lst> |
|||
# @print The element found |
|||
# |
|||
list_back () { |
|||
test "$#" -ne 1 && return 1; echo "$@" | sed -n '$p' |
|||
} |
|||
|
|||
## |
|||
# @brief Removes the first-hit element from a list |
|||
# @usage list_erase <elt> <lst> |
|||
# @print The list result |
|||
# |
|||
list_erase () { |
|||
test "$#" -ne 2 && return 1; echo "$2" | sed -e "0,/^$1$/ s///" -e '/^$/d' |
|||
} |
|||
|
|||
## |
|||
# @brief Removes a range of elements from a list between two specified |
|||
# positions |
|||
# @usage list_erase_range <from_index> <to_index> <lst> |
|||
# @print The list result |
|||
# |
|||
list_erase_range () { |
|||
test "$#" -ne 3 && return 1 |
|||
i="$1"; j="$2"; i=$((i+1)); j=$((j+1)); echo "$3" | sed "${i},${j}d" |
|||
} |
|||
|
|||
## |
|||
# @brief Removes all elements from a specified position |
|||
# @usage list_erase_from <index> <lst> |
|||
# @print The list result |
|||
# |
|||
list_erase_from () { |
|||
test "$#" -ne 2 && return 1; i="$1"; i=$((i+1)); echo "$2" | sed "${i},\$d" |
|||
} |
|||
|
|||
## |
|||
# @brief Removes the element at a specified position |
|||
# @usage list_eraseat <index> <lst> |
|||
# @print The list result |
|||
# |
|||
list_eraseat () { |
|||
test "$#" -ne 2 && return 1; i="$1"; i=$((i+1)); echo "$2" | sed "${i}d" |
|||
} |
|||
|
|||
## |
|||
# @brief Removes all the elements from the list, which are equal to given |
|||
# element |
|||
# @usage list_remove <elt> <lst> |
|||
# @print The list result |
|||
# |
|||
list_remove () { |
|||
test "$#" -ne 2 && return 1; echo "$2" | sed -e "/^$1$/d" |
|||
} |
|||
|
|||
## |
|||
# @brief Removes the first element of the list |
|||
# @usage list_pop_front <lst> |
|||
# @print The list result |
|||
# |
|||
list_pop_front () { |
|||
test "$#" -ne 1 && return 1; echo "$1" | sed '1d' |
|||
} |
|||
|
|||
## |
|||
# @brief Removes the last element of the list |
|||
# @usage list_pop_back <lst> |
|||
# @print The list result |
|||
# |
|||
list_pop_back () { |
|||
test "$#" -ne 1 && return 1; echo "$1" | sed '$d' |
|||
} |
|||
|
|||
## |
|||
# @brief Prints the index of a specified element |
|||
# @usage list_indexof <elt> <lst> |
|||
# @print The index or empty string if the element is not found |
|||
# |
|||
list_indexof () { |
|||
test "$#" -ne 2 && return 1; i=0 |
|||
for e in $2; do |
|||
[ "$e" = "$1" ] && { echo "$i"; return 0; }; i=$((i+1)); |
|||
done |
|||
return 1 |
|||
} |
|||
|
|||
## |
|||
# @brief Returns whether the list contains a specified element(0) or not(1) |
|||
# @usage list_contains <elt> <lst> |
|||
# @return 0 or 1 |
|||
# |
|||
list_contains () { |
|||
test "$#" -ne 2 && return 1 |
|||
for e in $2; do [ "$e" = "$1" ] && return 0; done; return 1 |
|||
} |
|||
|
|||
## |
|||
# @brief Counts the number of a specified element in the list |
|||
# @usage list_count <elt> <lst> |
|||
# @print The number of elements as positive integer |
|||
# |
|||
list_count () { |
|||
test "$#" -ne 2 && return 1 |
|||
i=0; for e in $2; do [ "$e" = "$1" ] && { i=$((i+1)); }; done; echo "$i" |
|||
} |
|||
|
|||
## |
|||
# @brief Maps every element of the list |
|||
# @usage list_maps <func> <lst> |
|||
# @print The list result |
|||
# |
|||
list_map () { |
|||
test "$#" -ne 2 && return 1; for e in $2; do eval "$1 $e"; done |
|||
} |
|||
|
|||
## |
|||
# @brief Reverses the list |
|||
# @usage list_reverse <lst> |
|||
# @print The list result |
|||
# |
|||
list_reverse() { |
|||
test "$#" -ne 1 && return 1; echo "$1" | sed '1!x;H;1h;$!d;g' |
|||
} |
|||
|
|||
## |
|||
# @brief Sorts the list |
|||
# @usage list_sort <lst> |
|||
# @print The list result |
|||
# |
|||
list_sort () { |
|||
test "$#" -ne 1 && return 1; echo "$1" | sort -n |
|||
} |
|||
|
|||
## |
|||
# @brief Sorts and reverses the sense of the list |
|||
# @usage list_sort_reverse <lst> |
|||
# @print The list result |
|||
# |
|||
list_sort_reverse () { |
|||
test "$#" -ne 1 && return 1; echo "$1" | sort -nr |
|||
} |
@ -0,0 +1,286 @@ |
|||
#!/bin/sh |
|||
# |
|||
# The MIT License (MIT) |
|||
# |
|||
# Copyright (c) 2017-2018 Thomas "Ventto" Venriès <thomas.venries@gmail.com> |
|||
# |
|||
# 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. |
|||
|
|||
## |
|||
# @brief Prints a list from arguments |
|||
# @usage list <elt> <elt> ... |
|||
# @print The list result |
|||
# |
|||
list () { |
|||
for e; do [ -n "$e" ] && echo "$e"; done |
|||
} |
|||
|
|||
## |
|||
# @brief Prints the number of elements in the list |
|||
# @usage list_size <lst> |
|||
# @print The size of the list as positive integer |
|||
# |
|||
list_size () { |
|||
test "$#" -ne 1 && { echo "0"; return; } |
|||
eval "test -n \"\$$1\"" && { eval "echo \"\$$1\" | wc -l"; return; } |
|||
echo '0' |
|||
} |
|||
|
|||
## |
|||
# @brief Returns whether the list is empty(1) or not(0) |
|||
# @usage list_empty <lst> |
|||
# @return 0 or 1 |
|||
# |
|||
list_empty () { |
|||
eval "test -z \"\$$1\"" |
|||
} |
|||
|
|||
## |
|||
# @brief Adds a new element at the beginning of the list |
|||
# @usage list_push_front <lst> <elt> |
|||
# @out Set the variable passed by reference |
|||
# |
|||
list_push_front () { |
|||
test "$#" -ne 2 && return 1 |
|||
eval "test -n \"\$$1\"" || { eval "$1='$2'"; return; } |
|||
eval "$1=\"\$(printf '%s\n%s' '$2' \"\$$1\")\""; |
|||
} |
|||
|
|||
## |
|||
# @brief Adds a new element at the end of the list |
|||
# @usage list_push_back <lst> <elt> |
|||
# @out Set the variable passed by reference |
|||
# |
|||
list_push_back () { |
|||
test "$#" -ne 2 && return 1 |
|||
eval "test -n \"\$$1\"" || { eval "$1='$2'"; return; } |
|||
eval "test -n \"\$$1\"" || { eval "$1='$2'"; return; } |
|||
eval "$1=\"\$(printf '%s\n%s' \"\$$1\" '$2')\""; |
|||
} |
|||
|
|||
## |
|||
# @brief Inserts new elements in the list before a specified position |
|||
# @usage list_insert <lst> <elt> <index> |
|||
# @out Set the variable passed by reference |
|||
# |
|||
list_insert () { |
|||
test "$#" -ne 3 && return 1; i="$3"; [ "$i" != '$' ] && i=$((i+1)) |
|||
eval "$1=\"\$(echo \"\$$1\" | sed \"${i}i${2}\")\"" |
|||
} |
|||
|
|||
## |
|||
# @brief Modifies an element from the list at a specified position |
|||
# @usage list_set <lst> <elt> <index> |
|||
# @out Set the variable passed by reference |
|||
# |
|||
list_set () { |
|||
test "$#" -ne 3 && return 1 |
|||
i="$3"; i=$((i+1)); eval "$1=\"\$(echo \"\$$1\" | sed \"${i}s/.*/$2/\")\"" |
|||
} |
|||
|
|||
## |
|||
# @brief Extracts a range of elements from the list between two specified |
|||
# positions |
|||
# @usage list_extract <lst> <from_index> <to_index> |
|||
# @out Set the variable passed by reference |
|||
# |
|||
list_extract () { |
|||
test "$#" -ne 3 && return 1; i="$2"; j="$3"; i=$((i+1)); j=$((j+1)) |
|||
eval "$1=\"\$(echo \"\$$1\" | sed -n \"${i},${j}p\")\"" |
|||
} |
|||
|
|||
## |
|||
# @brief Replaces all elements from the list with a specified element |
|||
# @usage list_replace <lst> <old_elt> <new_elt> |
|||
# @out Set the variable passed by reference |
|||
# |
|||
list_replace () { |
|||
test "$#" -ne 3 && return 1 |
|||
eval "$1=\"\$(echo \"\$$1\" | sed -e \"s/^$2$/$3/g\")\"" |
|||
} |
|||
|
|||
## |
|||
# @brief Prints the element at a specified position |
|||
# @usage list_get <lst> <index> |
|||
# @print The element found |
|||
# |
|||
list_get () { |
|||
test "$#" -ne 2 && return 1; i="$2"; i=$((i+1)); |
|||
eval "echo \"\$$1\" | sed -n \"${i}p\"" |
|||
} |
|||
|
|||
## |
|||
# @brief Prints the head of the list |
|||
# @usage list_front <lst> |
|||
# @print The element found |
|||
# |
|||
list_front () { |
|||
test "$#" -ne 1 && return 1; eval "echo \"\$$1\" | sed -n '1p'" |
|||
} |
|||
|
|||
## |
|||
# @brief Prints the queue of the list |
|||
# @usage list_back <lst> |
|||
# @print The element found |
|||
# |
|||
list_back () { |
|||
test "$#" -ne 1 && return 1; eval "echo \"\$$1\" | sed -n '\$p'" |
|||
} |
|||
|
|||
## |
|||
# @brief Removes the first-hit element from a list |
|||
# @usage list_erase <lst> <elt> |
|||
# @out Set the variable passed by reference |
|||
# |
|||
list_erase () { |
|||
test "$#" -ne 2 && return 1 |
|||
eval "$1=\"\$(echo \"\$$1\" | sed -e \"0,/^$2$/ s///\" -e '/^$/d')\"" |
|||
} |
|||
|
|||
## |
|||
# @brief Removes a range of elements from a list between two specified |
|||
# positions |
|||
# @usage list_erase_range <lst> <from_index> <to_index> |
|||
# @out Set the variable passed by reference |
|||
# |
|||
list_erase_range () { |
|||
test "$#" -ne 3 && return 1 |
|||
i="$2"; j="$3"; i=$((i+1)); j=$((j+1)); |
|||
eval "$1=\"\$(echo \"\$$1\" | sed \"${i},${j}d\")\"" |
|||
} |
|||
|
|||
## |
|||
# @brief Removes all elements from a specified position |
|||
# @usage list_erase_from <lst> <index> |
|||
# @out Set the variable passed by reference |
|||
# |
|||
list_erase_from () { |
|||
test "$#" -ne 2 && return 1 |
|||
i="$2"; i=$((i+1)); eval "$1=\"\$(echo \"\$$1\" | sed \"${i},\\\$d\")\"" |
|||
} |
|||
|
|||
## |
|||
# @brief Removes the element at a specified position |
|||
# @usage list_eraseat <lst> <index> |
|||
# @out Set the variable passed by reference |
|||
# |
|||
list_eraseat () { |
|||
test "$#" -ne 2 && return 1 |
|||
i="$2"; i=$((i+1)); eval "$1=\"\$(echo \"\$$1\" | sed \"${i}d\")\"" |
|||
} |
|||
|
|||
## |
|||
# @brief Removes all the elements from the list, which are equal to given |
|||
# element |
|||
# @usage list_remove <lst> <elt> |
|||
# @out Set the variable passed by reference |
|||
# |
|||
list_remove () { |
|||
test "$#" -ne 2 && return 1 |
|||
eval "$1=\"\$(echo \"\$$1\" | sed -e \"/^$2$/d\")\"" |
|||
} |
|||
|
|||
## |
|||
# @brief Removes the first element of the list |
|||
# @usage list_pop_front <lst> |
|||
# @out Set the variable passed by reference |
|||
# |
|||
list_pop_front () { |
|||
test "$#" -ne 1 && return 1; eval "$1=\"\$(echo \"\$$1\" | sed '1d')\"" |
|||
} |
|||
|
|||
## |
|||
# @brief Removes the last element of the list |
|||
# @usage list_pop_back <lst> |
|||
# @out Set the variable passed by reference |
|||
# |
|||
list_pop_back () { |
|||
test "$#" -ne 1 && return 1; eval "$1=\"\$(echo \"\$$1\" | sed '\$d')\"" |
|||
} |
|||
|
|||
## |
|||
# @brief Prints the index of a specified element |
|||
# @usage list_indexof <lst> <elt> |
|||
# @print positive integer or -1 if not found |
|||
# |
|||
list_indexof () { |
|||
test "$#" -ne 2 && return 1; i=0 |
|||
eval "for e in \$$1; do |
|||
[ \"\$e\" = '$2' ] && { echo \"\$i\"; return 0; }; i=\$((i+1)); |
|||
done" |
|||
return 1 |
|||
} |
|||
|
|||
## |
|||
# @brief Returns whether the list contains a specified element(0) or not(1) |
|||
# @usage list_contains <lst> <elt> |
|||
# @return 0 or 1 |
|||
# |
|||
list_contains () { |
|||
test "$#" -ne 2 && return 1 |
|||
eval "for e in \$$1; do [ \"\$e\" = '$2' ] && return 0; done; return 1" |
|||
} |
|||
|
|||
## |
|||
# @brief Prints the number of a specified element in the list |
|||
# @usage list_count <lst> <elt> |
|||
# @print The number of elements as positive integer |
|||
# |
|||
list_count () { |
|||
test "$#" -ne 2 && { echo '0'; return; } |
|||
eval "i=0; for e in \$$1; do [ \"\$e\" = '$2' ] && { i=\$((i+1)); };done;" |
|||
echo "$i" |
|||
} |
|||
|
|||
## |
|||
# @brief Maps every element of the list |
|||
# @usage list_maps <lst> <func> |
|||
# @out Set the variable passed by reference |
|||
# |
|||
list_map () { |
|||
test "$#" -ne 2 && return 1 |
|||
eval "$1=\"\$(for e in \$$1; do eval \"$2 \$e\"; done)\"" |
|||
} |
|||
|
|||
## |
|||
# @brief Reverses the list |
|||
# @usage list_reverse <lst> |
|||
# @out Set the variable passed by reference |
|||
# |
|||
list_reverse() { |
|||
test "$#" -ne 1 && return 1 |
|||
eval "$1=\"\$(echo \"\$$1\" | sed '1!x;H;1h;\$!d;g')\"" |
|||
} |
|||
|
|||
## |
|||
# @brief Sorts the list |
|||
# @usage list_sort <lst> |
|||
# @out Set the variable passed by reference |
|||
# |
|||
list_sort () { |
|||
test "$#" -ne 1 && return 1; eval "$1=\"\$(echo \"\$$1\" | sort -n)\"" |
|||
} |
|||
|
|||
## |
|||
# @brief Sorts and reverses the sense of the list |
|||
# @usage list_sort_reverse <lst> |
|||
# @out Set the variable passed by reference |
|||
# |
|||
list_sort_reverse () { |
|||
test "$#" -ne 1 && return 1; eval "$1=\"\$(echo \"\$$1\" | sort -nr)\"" |
|||
} |
@ -0,0 +1,85 @@ |
|||
#!/bin/sh |
|||
|
|||
. ./liblist.sh |
|||
|
|||
print_list () { |
|||
echo '==========List============' |
|||
printf "%s\n" "$1" |
|||
echo '--------------------------' |
|||
printf "Size: %s\t\n\n" "$(list_size "$1")" |
|||
} |
|||
|
|||
Test_Delete () { |
|||
lst="$(list '1' '12' '23' \ |
|||
'33' '215' '-456' \ |
|||
'1236' '1' '12' \ |
|||
'3' '-3' '33' \ |
|||
'1' '12' '-55' \ |
|||
'123' '-1002' '-1' )" |
|||
|
|||
printf "TEST: Deletion\n\n" |
|||
echo 'test: Initialization'; print_list "$lst" |
|||
|
|||
lst="$(list_remove '1' "$lst")" ; echo 'test:' ; print_list "$lst" |
|||
lst="$(list_erase '33' "$lst")" ; echo 'test:' ; print_list "$lst" |
|||
lst="$(list_eraseat '3' "$lst")" ; echo 'test:' ; print_list "$lst" |
|||
lst="$(list_pop_front "$lst")" ; echo 'test:' ; print_list "$lst" |
|||
lst="$(list_pop_back "$lst")" ; echo 'test:' ; print_list "$lst" |
|||
lst="$(list_erase_from '8' "$lst")" ; echo 'test:' ; print_list "$lst" |
|||
lst="$(list_erase_range '1' '2' "$lst")"; echo 'test:' ; print_list "$lst" |
|||
lst="$(list_erase_range '0' '0' "$lst")"; echo 'test:' ; print_list "$lst" |
|||
lst="$(list_extract '1' '3' "$lst")" ; echo 'test:' ; print_list "$lst" |
|||
lst="$(list_extract '1' '30' "$lst")" ; echo 'test:' ; print_list "$lst" |
|||
lst="$(list_extract '1' '0' "$lst")" ; echo 'test:' ; print_list "$lst" |
|||
} |
|||
|
|||
Test_Addition () { |
|||
lst= |
|||
|
|||
printf "TEST: Addition\n\n" |
|||
echo 'test: Initialization'; print_list "$lst" |
|||
|
|||
lst="$(list_push_front '12' "$lst")" ; echo 'test:' ; print_list "$lst" |
|||
lst="$(list_push_back '33' "$lst")" ; echo 'test:' ; print_list "$lst" |
|||
lst="$(list_push_front '1' "$lst")" ; echo 'test:' ; print_list "$lst" |
|||
lst="$(list_insert '23' '2' "$lst")" ; echo 'test:' ; print_list "$lst" |
|||
lst="$(list_push_back '215' "$lst")" ; echo 'test:' ; print_list "$lst" |
|||
} |
|||
|
|||
inc () { i="$1"; i=$((i+1)); echo "${i}"; } |
|||
Test_Set() { |
|||
lst="$(list '1' '12' '23' \ |
|||
'33' '215' '-456' \ |
|||
'1236' '1' '12' )" |
|||
|
|||
printf "TEST: Set\n\n" |
|||
echo 'test: Initialization'; print_list "$lst" |
|||
|
|||
lst="$(list_reverse "$lst")" ; echo 'test:' ; print_list "$lst" |
|||
lst="$(list_sort "$lst")" ; echo 'test:' ; print_list "$lst" |
|||
lst="$(list_sort_reverse "$lst")" ; echo 'test:' ; print_list "$lst" |
|||
lst="$(list_map inc "$lst")" ; echo 'test:' ; print_list "$lst" |
|||
lst="$(list_replace '2' '999' "$lst")" ; echo 'test:' ; print_list "$lst" |
|||
lst="$(list_set '999' '3' "$lst")" ; echo 'test:' ; print_list "$lst" |
|||
lst="$(list_set '999' '6' "$lst")" ; echo 'test:' ; print_list "$lst" |
|||
} |
|||
|
|||
Test_Get() { |
|||
lst="$(list '1' '12' '23' \ |
|||
'33' '215' '-456' \ |
|||
'1236' '1' '12' )" |
|||
|
|||
printf "TEST: Get\n\n" |
|||
echo 'test: Initialization'; print_list "$lst" |
|||
|
|||
printf 'test: elt=' ; list_front "$lst" |
|||
printf 'test: elt=' ; list_back "$lst" |
|||
printf 'test: elt=' ; list_get '2' "$lst" |
|||
printf 'test: index=' ; list_indexof '1' "$lst" | grep -E '^[0-9]+$' || echo |
|||
printf 'test: index=' ; list_indexof '-456' "$lst" | grep -E '^[0-9]+$' || echo |
|||
printf 'test: contains='; list_contains '1236' "$lst" && echo 'yes' || echo 'no' |
|||
printf 'test: contains='; list_contains '999' "$lst" && echo 'yes' || echo 'no' |
|||
printf 'test: count=' ; list_count '1' "$lst" |
|||
printf 'test: count=' ; list_count '215' "$lst" |
|||
printf 'test: empty=' ; list_empty "$lst" && echo 'yes' || echo 'no' |
|||
} |
@ -0,0 +1,210 @@ |
|||
#!/bin/sh |
|||
|
|||
. ./liblist_unsafe.sh |
|||
|
|||
print_list () { |
|||
echo '==========List============' |
|||
eval "printf \"%s\\n\" \"\$$1\"" |
|||
echo '--------------------------' |
|||
eval "printf \"Size: %s\t\n\n\" \"\$(list_size $1)\"" |
|||
} |
|||
|
|||
Test_Delete () { |
|||
lst="$(list '1' '12' '23' \ |
|||
'33' '215' '-456' \ |
|||
'1236' '1' '12' \ |
|||
'3' '-3' '33' \ |
|||
'1' '12' '-55' \ |
|||
'123' '-1002' '-1' )" |
|||
|
|||
printf "TEST: Deletion\n\n" |
|||
echo 'test: Initialization'; print_list lst |
|||
|
|||
list_remove lst '1' ; echo 'test:' ; print_list lst |
|||
list_erase lst '33' ; echo 'test:' ; print_list lst |
|||
list_eraseat lst 3 ; echo 'test:' ; print_list lst |
|||
list_pop_front lst ; echo 'test:' ; print_list lst |
|||
list_pop_back lst ; echo 'test:' ; print_list lst |
|||
list_erase_from lst 8 ; echo 'test:' ; print_list lst |
|||
list_erase_range lst 1 2 ; echo 'test:' ; print_list lst |
|||
list_erase_range lst 0 0 ; echo 'test:' ; print_list lst |
|||
list_extract lst 1 3 ; echo 'test:' ; print_list lst |
|||
list_extract lst 1 30 ; echo 'test:' ; print_list lst |
|||
list_extract lst 1 0 ; echo 'test:' ; print_list lst |
|||
} |
|||
|
|||
Test_Addition () { |
|||
lst= |
|||
|
|||
printf "TEST: Addition\n\n" |
|||
echo 'test: Initialization'; print_list lst |
|||
|
|||
list_push_front lst '12' ; echo 'test:' ; print_list lst |
|||
list_push_back lst '33' ; echo 'test:' ; print_list lst |
|||
list_push_front lst '1' ; echo 'test:' ; print_list lst |
|||
list_insert lst '23' 2 ; echo 'test:' ; print_list lst |
|||
list_push_back lst '215' ; echo 'test:' ; print_list lst |
|||
} |
|||
|
|||
inc () { i="$1"; i=$((i+1)); echo "${i}"; } |
|||
Test_Set() { |
|||
lst="$(list '1' '12' '23' \ |
|||
'33' '215' '-456' \ |
|||
'1236' '1' '12' )" |
|||
|
|||
printf "TEST: Set\n\n" |
|||
echo 'test: Initialization'; print_list lst |
|||
|
|||
list_reverse lst ; echo 'test:' ; print_list lst |
|||
list_sort lst ; echo 'test:' ; print_list lst |
|||
list_sort_reverse lst ; echo 'test:' ; print_list lst |
|||
list_map lst inc ; echo 'test:' ; print_list lst |
|||
list_replace lst '2' '999' ; echo 'test:' ; print_list lst |
|||
list_set lst '999' 3 ; echo 'test:' ; print_list lst |
|||
list_set lst '999' 6 ; echo 'test:' ; print_list lst |
|||
} |
|||
|
|||
Test_Get() { |
|||
lst="$(list '1' '12' '23' \ |
|||
'33' '215' '-456' \ |
|||
'1236' '1' '12' )" |
|||
|
|||
printf "TEST: Set\n\n" |
|||
echo 'test: Initialization'; print_list lst |
|||
|
|||
printf 'test: elt=' ; list_front lst |
|||
printf 'test: elt=' ; list_back lst |
|||
printf 'test: elt=' ; list_get lst 2 |
|||
printf 'test: index=' ; list_indexof lst '1' | grep -E '^[0-9]+$' || echo |
|||
printf 'test: index=' ; list_indexof lst '-456' | grep -E '^[0-9]+$' || echo |
|||
printf 'test: contains='; list_contains lst '1236' && echo 'yes' || echo 'no' |
|||
printf 'test: contains='; list_contains lst '2' && echo 'yes' || echo 'no' |
|||
printf 'test: count=' ; list_count lst '1' |
|||
printf 'test: count=' ; list_count lst '215' |
|||
printf 'test: empty=' ; list_empty lst && echo 'yes' || echo 'no' |
|||
} |
|||
|
|||
Test_Void() { |
|||
lst="$(list '' '' '')" |
|||
|
|||
printf "TEST: Void\n\n" |
|||
echo 'test: Initialization'; print_list lst |
|||
|
|||
printf 'test (void): empty=' ; list_empty lst && echo 'yes' || echo 'no' |
|||
printf 'test (void): size=' ; list_size lst |
|||
|
|||
list_reverse lst ; echo 'test:' ; print_list lst |
|||
list_sort lst ; echo 'test:' ; print_list lst |
|||
list_sort_reverse lst ; echo 'test:' ; print_list lst |
|||
list_replace lst '2' '999' ; echo 'test:' ; print_list lst |
|||
list_set lst '999' 3 ; echo 'test:' ; print_list lst |
|||
list_set lst '999' 6 ; echo 'test:' ; print_list lst |
|||
list_map lst inc ; echo 'test:' ; print_list lst |
|||
list_remove lst '1' ; echo 'test:' ; print_list lst |
|||
list_erase lst '33' ; echo 'test:' ; print_list lst |
|||
list_eraseat lst 3 ; echo 'test:' ; print_list lst |
|||
list_pop_front lst ; echo 'test:' ; print_list lst |
|||
list_pop_back lst ; echo 'test:' ; print_list lst |
|||
list_erase_from lst 8 ; echo 'test:' ; print_list lst |
|||
list_erase_range lst 1 2 ; echo 'test:' ; print_list lst |
|||
list_erase_range lst 0 0 ; echo 'test:' ; print_list lst |
|||
list_extract lst 1 3 ; echo 'test:' ; print_list lst |
|||
list_extract lst 1 30 ; echo 'test:' ; print_list lst |
|||
list_extract lst 1 0 ; echo 'test:' ; print_list lst |
|||
list_push_front lst '2' ; echo 'test:' ; print_list lst |
|||
list_push_back lst '4' ; echo 'test:' ; print_list lst |
|||
list_push_front lst '1' ; echo 'test:' ; print_list lst |
|||
list_insert lst '3' 2 ; echo 'test:' ; print_list lst |
|||
list_push_back lst '5' ; echo 'test:' ; print_list lst |
|||
} |
|||
|
|||
Test_BadArg() { |
|||
lst="$1" |
|||
printf "TEST: BadArg\n\n" |
|||
echo 'test: Initialization'; print_list lst |
|||
|
|||
list_push_front lst ; echo 'test:' ; print_list lst |
|||
list_push_front '' ; echo 'test:' ; print_list lst |
|||
list_push_front ; echo 'test:' ; print_list lst |
|||
|
|||
list_push_back lst ; echo 'test:' ; print_list lst |
|||
list_push_back '' ; echo 'test:' ; print_list lst |
|||
list_push_back ; echo 'test:' ; print_list lst |
|||
|
|||
list_insert lst '' ; echo 'test:' ; print_list lst |
|||
list_insert lst ; echo 'test:' ; print_list lst |
|||
list_insert 2 ; echo 'test:' ; print_list lst |
|||
|
|||
list_reverse ; echo 'test:' ; print_list lst |
|||
list_sort ; echo 'test:' ; print_list lst |
|||
list_sort_reverse ; echo 'test:' ; print_list lst |
|||
|
|||
list_replace lst '2' ; echo 'test:' ; print_list lst |
|||
list_replace lst ; echo 'test:' ; print_list lst |
|||
list_replace ; echo 'test:' ; print_list lst |
|||
|
|||
list_set lst '999' ; echo 'test:' ; print_list lst |
|||
list_set lst ; echo 'test:' ; print_list lst |
|||
list_set ; echo 'test:' ; print_list lst |
|||
|
|||
list_map lst ; echo 'test:' ; print_list lst |
|||
list_map inc ; echo 'test:' ; print_list lst |
|||
list_map ; echo 'test:' ; print_list lst |
|||
|
|||
list_remove lst ; echo 'test:' ; print_list lst |
|||
list_remove '1' ; echo 'test:' ; print_list lst |
|||
list_remove ; echo 'test:' ; print_list lst |
|||
|
|||
list_erase lst ; echo 'test:' ; print_list lst |
|||
list_erase '33' ; echo 'test:' ; print_list lst |
|||
list_erase ; echo 'test:' ; print_list lst |
|||
|
|||
list_eraseat lst ; echo 'test:' ; print_list lst |
|||
list_eraseat 3 ; echo 'test:' ; print_list lst |
|||
list_eraseat ; echo 'test:' ; print_list lst |
|||
|
|||
list_pop_front ; echo 'test:' ; print_list lst |
|||
list_pop_back ; echo 'test:' ; print_list lst |
|||
|
|||
list_erase_from lst ; echo 'test:' ; print_list lst |
|||
list_erase_from 8 ; echo 'test:' ; print_list lst |
|||
list_erase_from ; echo 'test:' ; print_list lst |
|||
|
|||
list_erase_range lst 0 ; echo 'test:' ; print_list lst |
|||
list_erase_range lst ; echo 'test:' ; print_list lst |
|||
list_erase_range ; echo 'test:' ; print_list lst |
|||
|
|||
list_extract 0 1 ; echo 'test:' ; print_list lst |
|||
list_extract lst 1 ; echo 'test:' ; print_list lst |
|||
list_extract lst ; echo 'test:' ; print_list lst |
|||
list_extract ; echo 'test:' ; print_list lst |
|||
|
|||
printf 'test: elt=' ; list_front || echo |
|||
printf 'test: elt=' ; list_back || echo |
|||
|
|||
printf 'test: elt=' ; list_get lst || echo |
|||
printf 'test: elt=' ; list_get 2 || echo |
|||
printf 'test: elt=' ; list_get || echo |
|||
|
|||
printf 'test: index=' ; list_indexof lst | grep -E '^[0-9]+$' || echo |
|||
printf 'test: index=' ; list_indexof '-456' | grep -E '^[0-9]+$' || echo |
|||
printf 'test: index=' ; list_indexof | grep -E '^[0-9]+$' || echo |
|||
|
|||
printf 'test: contains='; list_contains lst && echo 'yes' || echo 'no' |
|||
printf 'test: contains='; list_contains '2' && echo 'yes' || echo 'no' |
|||
printf 'test: contains='; list_contains && echo 'yes' || echo 'no' |
|||
|
|||
printf 'test: count=' ; list_count lst |
|||
printf 'test: count=' ; list_count '215' |
|||
printf 'test: count=' ; list_count |
|||
|
|||
printf 'test: empty=' ; list_empty && echo 'yes' || echo 'no' |
|||
} |
|||
|
|||
Test_VoidBadArg() { |
|||
Test_BadArg "$(list '' '' '' '')" |
|||
} |
|||
|
|||
Test_WithBadArg() { |
|||
Test_BadArg "$(list 1 2 3)" |
|||
} |
@ -0,0 +1,448 @@ |
|||
#!/bin/sh |
|||
# |
|||
# The MIT License (MIT) |
|||
# |
|||
# Copyright (c) 2017-2018 Thomas "Ventto" Venriès <thomas.venries@gmail.com> |
|||
# |
|||
# 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. |
|||
usage() { |
|||
echo 'Usage: mons [OPTION]... |
|||
|
|||
Without argument, it prints connected monitors list with their names and ids. |
|||
Options are exclusive and can be used in conjunction with extra options. |
|||
|
|||
Information: |
|||
-h Prints this help and exits. |
|||
-v Prints version and exits. |
|||
|
|||
Two monitors: |
|||
-o Primary monitor only. |
|||
-s Second monitor only. |
|||
-d Duplicates the primary monitor. |
|||
-m Mirrors the primary monitor. |
|||
-e <side> |
|||
Extends the primary monitor to the selected side |
|||
[ top | left | right | bottom ]. |
|||
-n <side> |
|||
This mode selects the previous ones, one after another. The argument |
|||
sets the side for the extend mode. |
|||
|
|||
More monitors: |
|||
-O <mon> |
|||
Only enables the monitor with a specified id. |
|||
-S <mon1>,<mon2>:<pos> |
|||
Only enables two monitors with specified ids. The specified position |
|||
places the second monitor on the right (R) or at the top (T). |
|||
|
|||
Extra (in-conjunction or alone): |
|||
--dpi <dpi> |
|||
Set the DPI, a strictly positive value within the range [0 ; 27432]. |
|||
--primary <mon_name> |
|||
Select a connected monitor as the primary output. Run the script |
|||
without argument to print monitors information, the names are in the |
|||
second column between ids and status. The primary monitor is marked |
|||
by an asterisk. |
|||
|
|||
Daemon mode: |
|||
-a Performs an automatic display if it detects only one monitor. |
|||
' |
|||
} |
|||
|
|||
version() { |
|||
echo 'Mons 0.8.2 |
|||
Copyright (C) 2017 Thomas "Ventto" Venries. |
|||
|
|||
License MIT: <https://opensource.org/licenses/MIT>. |
|||
|
|||
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. |
|||
' |
|||
} |
|||
|
|||
# Helps to generate manpage with help2man before installing the library |
|||
[ "$1" = '-h' ] && { usage; exit; } |
|||
[ "$1" = '-v' ] && { version; exit; } |
|||
lib='/usr/lib/libshlist/liblist.sh' |
|||
[ ! -r "$lib" ] && { "$lib: library not found."; exit 1; } |
|||
. "${lib}" |
|||
|
|||
arg_err() { |
|||
usage ; exit 2 |
|||
} |
|||
|
|||
enable_mon() { |
|||
"${XRANDR}" --output "${1}" --auto --dpi "${dpi}" |
|||
} |
|||
|
|||
disable_mons() { |
|||
for mon in $@; do "${XRANDR}" --output "${mon}" --off ; done |
|||
} |
|||
|
|||
arg2xrandr() { |
|||
case $1 in |
|||
left) echo '--left-of' ;; |
|||
right) echo '--right-of' ;; |
|||
bottom) echo '--below' ;; |
|||
top) echo '--above' ;; |
|||
esac |
|||
} |
|||
|
|||
whichmode() { |
|||
if [ "$(list_size "${disp_mons}")" -eq 1 ]; then |
|||
if echo "${enabled_out}" | grep prima > /dev/null 2>&1; then |
|||
echo 'primary' |
|||
else |
|||
echo 'second' |
|||
fi |
|||
else |
|||
if [ "$(list_size "${plug_mons}")" -gt 2 ] ; then |
|||
echo 'selection'; return 0 |
|||
fi |
|||
|
|||
enabled_out="$(echo "${enabled_out}" | \ |
|||
sed 's/^.*\( [0-9]\+\x[0-9]\++[0-9]\++[0-9]\+\).*/\1/')" |
|||
|
|||
echo "${enabled_out}" | head -n1 | sed -e 's/+/ /g' | \ |
|||
while read -r trash x1 y1; do |
|||
echo "${enabled_out}" | tail -n1 | sed -e 's/x/ /' -e 's/+/ /g' | \ |
|||
while read -r w2 h2 x2 y2; do |
|||
echo "${xrandr_out}" | \ |
|||
awk "/^$(list_get 1 "${plug_mons}")/{nr[NR+1]}; NR in nr" | \ |
|||
awk '{print $1;}' | sed -e 's/x/ /' | \ |
|||
while read -r wi2 hi2; do |
|||
if [ "$x1" = "$x2" ] && [ "$y1" = "$y2" ]; then |
|||
if [ "$w2" != "$wi2" ] || [ "$h2" != "$hi2" ]; then |
|||
echo 'mirror' |
|||
else |
|||
echo 'duplicate' |
|||
fi |
|||
else |
|||
echo 'extend' |
|||
fi |
|||
done |
|||
done |
|||
done |
|||
fi |
|||
} |
|||
|
|||
main() { |
|||
aFlag=false |
|||
dFlag=false |
|||
eFlag=false |
|||
mFlag=false |
|||
nFlag=false |
|||
oFlag=false |
|||
sFlag=false |
|||
OFlag=false |
|||
SFlag=false |
|||
pFlag=false |
|||
iFlag=false |
|||
is_flag=false |
|||
# X has assumed 96 DPI and this is fine for many traditional monitors. |
|||
dpi=96 |
|||
primary= |
|||
|
|||
# getopts does not support long options. We convert them to short one. |
|||
for arg in "$@"; do |
|||
shift |
|||
case "$arg" in |
|||
--dpi) set -- "$@" '-i' ;; |
|||
--primary) set -- "$@" '-p' ;; |
|||
*) set -- "$@" "$arg" |
|||
esac |
|||
done |
|||
|
|||
while getopts 'hvamosde:n:O:S:i:p:' opt; do |
|||
case $opt in |
|||
# Long options |
|||
i) |
|||
if ! echo "${OPTARG}" | \ |
|||
grep -E '^[1-9][0-9]*$' > /dev/null 2>&1; then |
|||
arg_err |
|||
fi |
|||
iFlag=true; dpi="$OPTARG" |
|||
;; |
|||
p) if ! echo "${OPTARG}" | \ |
|||
grep -E '^[a-zA-Z][a-zA-Z0-9\-]+' > /dev/null 2>&1; then |
|||
arg_err |
|||
fi |
|||
pFlag=true; primary="$OPTARG" |
|||
;; |
|||
# Short options |
|||
a) $is_flag && arg_err |
|||
aFlag=true ; is_flag=true |
|||
;; |
|||
m) $is_flag && arg_err |
|||
mFlag=true ; is_flag=true |
|||
;; |
|||
o) $is_flag && arg_err |
|||
oFlag=true ; is_flag=true |
|||
;; |
|||
s) $is_flag && arg_err |
|||
sFlag=true ; is_flag=true |
|||
;; |
|||
d) $is_flag && arg_err |
|||
dFlag=true ; is_flag=true |
|||
;; |
|||
e|n) $is_flag && arg_err |
|||
case ${OPTARG} in |
|||
left | right | bottom | top) ;; |
|||
*) arg_err ;; |
|||
esac |
|||
eArg=$OPTARG |
|||
[ "$opt" = "e" ] && eFlag=true || nFlag=true ; is_flag=true |
|||
;; |
|||
O) $is_flag && arg_err |
|||
! echo "${OPTARG}" | grep -E '^[0-9]+$' > /dev/null && arg_err |
|||
OArg=$OPTARG |
|||
OFlag=true ; is_flag=true |
|||
;; |
|||
S) $is_flag && arg_err |
|||
idx1="$(echo "${OPTARG}" | cut -d',' -f1)" |
|||
idx2="$(echo "${OPTARG}" | cut -d',' -f2)" |
|||
area="$(echo "${idx2}" | cut -d ':' -f2)" |
|||
idx2="$(echo "${idx2}" | cut -d ':' -f1)" |
|||
! echo "${idx1}" | grep -E '^[0-9]+$' > /dev/null && arg_err |
|||
! echo "${idx2}" | grep -E '^[0-9]+$' > /dev/null && arg_err |
|||
! echo "${area}" | grep -E '^[RT]$' > /dev/null && arg_err |
|||
[ "${idx1}" = "${idx2}" ] && arg_err |
|||
SFlag=true ; is_flag=true |
|||
;; |
|||
h) usage ; exit ;; |
|||
v) version ; exit ;; |
|||
\?) arg_err ;; |
|||
:) arg_err ;; |
|||
esac |
|||
done |
|||
|
|||
[ -z "${DISPLAY}" ] && { echo 'DISPLAY: no variable set.'; exit 1; } |
|||
|
|||
XRANDR="$(command -v xrandr)" |
|||
[ "$?" -ne 0 ] && { echo 'xrandr: command not found.'; exit 1; } |
|||
|
|||
# DPI set |
|||
$iFlag && [ "$#" -eq 2 ] && { "${XRANDR}" --dpi "$dpi"; exit; } |
|||
|
|||
# Daemon mode |
|||
if $aFlag ; then |
|||
prev=0; i=0 |
|||
while true; do |
|||
for status in /sys/class/drm/*/status; do |
|||
[ "$(<"$status")" = 'connected' ] && i=$((i+1)) |
|||
done |
|||
if [ "$i" -eq 1 ] && [ "$i" != "$prev" ]; then |
|||
"${XRANDR}" --auto --dpi "${dpi}" |
|||
fi |
|||
prev="$i"; i=0 |
|||
sleep 2 |
|||
done |
|||
fi |
|||
|
|||
# List all outputs (except primary one) |
|||
xrandr_out="$("${XRANDR}")" |
|||
enabled_out="$(echo "${xrandr_out}" | grep 'connect')" |
|||
[ -z "${enabled_out}" ] && { echo 'No monitor output detected.'; exit; } |
|||
mons="$(echo "${enabled_out}" | cut -d' ' -f1)" |
|||
|
|||
# List plugged-in and turned-on outputs |
|||
enabled_out="$(echo "${enabled_out}" | grep ' connect')" |
|||
[ -z "${enabled_out}" ] && { echo 'No plugged-in monitor detected.'; exit 1; } |
|||
plug_mons="$(echo "${enabled_out}" | cut -d' ' -f1)" |
|||
|
|||
if [ "$(list_size "${plug_mons}")" -eq 0 ]; then |
|||
echo "No monitor plugged-in." |
|||
exit 0 |
|||
fi |
|||
|
|||
# Set primary output |
|||
if $pFlag; then |
|||
if ! list_contains "${primary}" "${plug_mons}"; then |
|||
echo "${primary}: output not connected." |
|||
exit 1 |
|||
fi |
|||
"${XRANDR}" --output "${primary}" --primary |
|||
[ "$#" -eq 2 ] && exit |
|||
else |
|||
primary="$(echo "${enabled_out}" | grep 'primary' | cut -d' ' -f1)" |
|||
fi |
|||
|
|||
# Move the primary monitor to the head if connected otherwise the first |
|||
# connected monitor that appears in the xrandr output is considerate as |
|||
# the primary one. |
|||
if [ -n "${primary}" ]; then |
|||
plug_mons="$(list_erase "${primary}" "${plug_mons}")" |
|||
plug_mons="$(list_insert "${primary}" 0 "${plug_mons}")" |
|||
fi |
|||
|
|||
enabled_out="$(echo "${enabled_out}" | grep -E '\+[0-9]{1,4}\+[0-9]{1,4}')" |
|||
disp_mons="$(echo "${enabled_out}" | cut -d' ' -f1)" |
|||
|
|||
if [ "$#" -eq 0 ]; then |
|||
echo "Monitors: $(list_size "${plug_mons}")" |
|||
echo "Mode: $(whichmode)" |
|||
|
|||
i=0 |
|||
for mon in ${mons}; do |
|||
if echo "${plug_mons}" | grep "^${mon}$" > /dev/null; then |
|||
if echo "${disp_mons}" | grep "^${mon}$" > /dev/null; then |
|||
state='(enabled)' |
|||
fi |
|||
if [ "${mon}" = "${primary}" ]; then |
|||
printf '%-4s %-8s %-8s %-8s\n' "${i}:*" "${mon}" "${state}" |
|||
else |
|||
printf '%-4s %-8s %-8s\n' "${i}:" "${mon}" "${state}" |
|||
fi |
|||
fi |
|||
i=$((i+1)) |
|||
state= |
|||
done |
|||
exit |
|||
fi |
|||
|
|||
if $nFlag ; then |
|||
case "$(whichmode)" in |
|||
primary) sFlag=true;; |
|||
second) eFlag=true;; |
|||
extend) mFlag=true;; |
|||
mirror) dFlag=true;; |
|||
duplicate) oFlag=true;; |
|||
esac |
|||
fi |
|||
|
|||
if [ "$(list_size "${plug_mons}")" -eq 1 ] ; then |
|||
if $oFlag ; then |
|||
# After unplugging each monitor, the last preferred one might be |
|||
# still turned off or the window manager might need the monitor |
|||
# reset to cause the reconfiguration of the layout placement. |
|||
"${XRANDR}" --auto --dpi "${dpi}" |
|||
else |
|||
echo 'Only one monitor detected.' |
|||
fi |
|||
exit |
|||
fi |
|||
|
|||
if $oFlag ; then |
|||
if [ "$(list_size "${disp_mons}")" -eq 1 ]; then |
|||
if [ "$(list_front "${disp_mons}")" = "$(list_front "${plug_mons}")" ]; then |
|||
exit |
|||
fi |
|||
fi |
|||
disp_mons="$(list_erase "$(list_front "${plug_mons}")" "$disp_mons")" |
|||
disable_mons "${disp_mons}" |
|||
enable_mon "$(list_front "${plug_mons}")" |
|||
exit |
|||
fi |
|||
|
|||
if $OFlag ; then |
|||
if [ "${OArg}" -ge "$(list_size "${mons}")" ] ; then |
|||
echo "Monitor ID '${OArg}' does not exist." |
|||
echo 'Try without option to get monitor ID list.' |
|||
exit 2 |
|||
fi |
|||
mons_elt="$(list_get "${OArg}" "${mons}")" |
|||
if ! list_contains "${mons_elt}" "${plug_mons}"; then |
|||
echo "Monitor ID '${OArg}' not plugged in." |
|||
echo 'Try without option to get monitor ID list.' |
|||
exit 2 |
|||
fi |
|||
|
|||
disp_mons="$(list_erase "${mons_elt}" "${disp_mons}")" |
|||
disable_mons "${disp_mons}" |
|||
enable_mon "${mons_elt}" |
|||
exit |
|||
fi |
|||
|
|||
if $SFlag ; then |
|||
if [ "${idx1}" -ge "$(list_size "${mons}")" ] || \ |
|||
[ "${idx2}" -ge "$(list_size "${mons}")" ]; then |
|||
echo 'One or both monitor IDs do not exist.' |
|||
echo 'Try without option to get monitor ID list.' |
|||
exit 2 |
|||
fi |
|||
if ! list_contains "$(list_get "${idx1}" "${mons}")" "${plug_mons}" || \ |
|||
! list_contains "$(list_get "${idx2}" "${mons}")" "${plug_mons}" ; then |
|||
echo 'One or both monitor IDs are not plugged in.' |
|||
echo 'Try without option to get monitor ID list.' |
|||
exit 2 |
|||
fi |
|||
|
|||
[ "${area}" = 'R' ] && area="--right-of" || area="--above" |
|||
|
|||
mon1="$(list_get "${idx1}" "${mons}")" |
|||
mon2="$(list_get "${idx2}" "${mons}")" |
|||
disp_mons="$(list_erase "${mon1}" "${disp_mons}")" |
|||
disp_mons="$(list_erase "${mon2}" "${disp_mons}")" |
|||
disable_mons "${disp_mons}" |
|||
enable_mon "${mon1}" |
|||
enable_mon "${mon2}" |
|||
"${XRANDR}" --output "${mon2}" "${area}" "${mon1}" |
|||
exit |
|||
fi |
|||
|
|||
if [ "$(list_size "${plug_mons}")" -eq 2 ]; then |
|||
if $sFlag ; then |
|||
if [ "$(list_size "${disp_mons}")" -eq 1 ] ; then |
|||
if [ "$(list_front "${disp_mons}")" = "$(list_get 1 "${plug_mons}")" ] ; then |
|||
enable_mon "$(list_get 1 "${plug_mons}")" |
|||
exit |
|||
fi |
|||
fi |
|||
enable_mon "$(list_get 1 "${plug_mons}")" |
|||
disable_mons "$(list_front "${disp_mons}")" |
|||
exit |
|||
fi |
|||
|
|||
# Resets the screen configuration |
|||
disable_mons "$(list_get 1 "${plug_mons}")" |
|||
"${XRANDR}" --auto --dpi "${dpi}" |
|||
|
|||
if $dFlag ; then |
|||