Added
Signed-off-by: Marcin Woźniak <y0rune@aol.com>
This commit is contained in:
commit
7b2650b646
57
CONTRIBUTING.md
Normal file
57
CONTRIBUTING.md
Normal file
@ -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
|
20
LICENSE
Normal file
20
LICENSE
Normal file
@ -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.
|
37
Makefile
Normal file
37
Makefile
Normal file
@ -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
|
200
README.md
Normal file
200
README.md
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
Mons
|
||||||
|
===================
|
||||||
|
[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](https://github.com/Ventto/mons/blob/master/LICENSE)
|
||||||
|
[![Language (XRandR)](https://img.shields.io/badge/powered_by-XRandR-brightgreen.svg)](https://www.x.org/archive/X11R7.5/doc/man/man1/xrandr.1.html)
|
||||||
|
[![Vote for mons](https://img.shields.io/badge/AUR-Vote_for-yellow.svg)](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.
|
||||||
|
|
||||||
|
![alt 2-monitors modes](img/raw-body.png)
|
||||||
|
|
||||||
|
```
|
||||||
|
# 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)
|
||||||
|
```
|
19
_gitignore
Normal file
19
_gitignore
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
!libshlist
|
||||||
|
|
||||||
|
!img
|
||||||
|
img/*
|
||||||
|
!img/raw-body.png
|
||||||
|
|
||||||
|
!test
|
||||||
|
test/*
|
||||||
|
!test/*.sh
|
||||||
|
|
||||||
|
!mons
|
||||||
|
!CONTRIBUTING.md
|
||||||
|
!LICENSE
|
||||||
|
!Makefile
|
||||||
|
!README.md
|
||||||
|
!.gitignore
|
||||||
|
!.gitmodules
|
3
_gitmodules
Normal file
3
_gitmodules
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "libshlist"]
|
||||||
|
path = libshlist
|
||||||
|
url = https://github.com/Ventto/libshlist.git
|
BIN
img/raw-body.png
Normal file
BIN
img/raw-body.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.8 KiB |
20
libshlist/LICENSE
Normal file
20
libshlist/LICENSE
Normal file
@ -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.
|
111
libshlist/README.md
Normal file
111
libshlist/README.md
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
POSIX Shell List
|
||||||
|
================
|
||||||
|
|
||||||
|
[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](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
|
||||||
|
```
|
1
libshlist/_git
Normal file
1
libshlist/_git
Normal file
@ -0,0 +1 @@
|
|||||||
|
gitdir: ../.git/modules/libshlist
|
271
libshlist/liblist.sh
Normal file
271
libshlist/liblist.sh
Normal file
@ -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
|
||||||
|
}
|
286
libshlist/liblist_unsafe.sh
Normal file
286
libshlist/liblist_unsafe.sh
Normal file
@ -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)\""
|
||||||
|
}
|
85
libshlist/test/test.sh
Normal file
85
libshlist/test/test.sh
Normal file
@ -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'
|
||||||
|
}
|
210
libshlist/test/test_unsafe.sh
Normal file
210
libshlist/test/test_unsafe.sh
Normal file
@ -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)"
|
||||||
|
}
|
448
mons
Normal file
448
mons
Normal file
@ -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
|
||||||
|
"${XRANDR}" --output "$(list_get 1 "${plug_mons}")" \
|
||||||
|
--same-as "$(list_front "${plug_mons}")"
|
||||||
|
exit $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
if $mFlag ; then
|
||||||
|
xrandr_out="$(echo "${xrandr_out}" | \
|
||||||
|
awk "/primary/{nr[NR]; nr[NR+1]}; NR in nr")"
|
||||||
|
if echo "${xrandr_out}" | \
|
||||||
|
grep -E 'primary [0-9]+x[0-9]+' >/dev/null 2>&1; then
|
||||||
|
size="$(echo "${xrandr_out}" | head -n1 | cut -d' ' -f4 | \
|
||||||
|
cut -d'+' -f1)"
|
||||||
|
else
|
||||||
|
size="$(echo "${xrandr_out}" | tail -n1 | awk '{ print $1 }')"
|
||||||
|
fi
|
||||||
|
|
||||||
|
"${XRANDR}" --output "$(list_get 1 "${plug_mons}")" \
|
||||||
|
--auto --scale-from "${size}" \
|
||||||
|
--output "$(list_front "${plug_mons}")"
|
||||||
|
exit $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
if $eFlag ; then
|
||||||
|
"${XRANDR}" --output "$(list_get 1 "${plug_mons}")" \
|
||||||
|
"$(arg2xrandr "$eArg")" "$(list_front "${plug_mons}")"
|
||||||
|
exit $?
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo 'At most two plugged monitors for this option.'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
77
test/test-args.sh
Normal file
77
test/test-args.sh
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
if [ "$#" -ne 3 ]; then
|
||||||
|
echo 'Usage: test-args.sh MON_ID1 MON_ID2 MON_ID3'
|
||||||
|
echo
|
||||||
|
echo 'Three monitor ids are required. Ids are given by `mons`.'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 'TEST: Bad Arguments'
|
||||||
|
echo '#=========================#'
|
||||||
|
./mons
|
||||||
|
echo '#=========================#'
|
||||||
|
echo 'test: common'
|
||||||
|
|
||||||
|
n=1
|
||||||
|
./mons --s -o >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons --o >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons -e fekl56 >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons -e 2 >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons -e pot >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons -d 2 >/dev/null 2>&1 || echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons -m 2 >/dev/null 2>&1 || echo "failed: $n" ; n=$((n+1))
|
||||||
|
|
||||||
|
echo 'test: single selection'
|
||||||
|
|
||||||
|
n=1
|
||||||
|
./mons -O 5 "$1" >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons -O abc "$2" >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons --O "$3" >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons -O >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
|
||||||
|
echo 'test: multi selection'
|
||||||
|
|
||||||
|
n=1
|
||||||
|
./mons -S >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons -S "$1,$2:P" >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons -S "$3,$2:5" >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons -S "$2:R" >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons -S "$3,$1" >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons -S "A,B:R" >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
|
||||||
|
echo 'test: dpi'
|
||||||
|
|
||||||
|
n=1
|
||||||
|
./mons --dpi >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons --dpi A >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons --dpi 0 >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons --dpi -0 >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons --dpi -5 >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons --dpi -3000 >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons --dpi -s 1 >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
# Weird configuration
|
||||||
|
./mons -e --dpi 96 left >/dev/null 2>&1 || echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons -n --dpi 72 right >/dev/null 2>&1 || echo "failed: $n" ; n=$((n+1))
|
||||||
|
|
||||||
|
echo 'test: primary'
|
||||||
|
n=1
|
||||||
|
./mons --primary >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons --primary -HDMI1 >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons --primary -HDMI1 >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons --primary 1HDMI >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons --primary -s 1 >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons -n --primary HDMI1 >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons -n --primary HDMI1 left >/dev/null 2>&1 || echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons -n --primary HDMI1 left -s >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
|
||||||
|
echo 'test: dpi + primary'
|
||||||
|
n=1
|
||||||
|
./mons --primary --dpi >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons --primary --dpi 75 >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons --primary HDMI1 --dpi >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons --primary HDMI1 --dpi 0 >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons --primary 1HDMI --dpi 0 >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons --primary HDMI1 --dpi HDMI1 >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons --primary HDMI1 --dpi 75 >/dev/null 2>&1 && echo "failed: $n" ; n=$((n+1))
|
||||||
|
./mons -n --primary HDMI1 --dpi 75 left >/dev/null 2>&1 || echo "failed: $n" ; n=$((n+1))
|
36
test/test-common.sh
Normal file
36
test/test-common.sh
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
if [ "$#" -ne 2 ]; then
|
||||||
|
echo 'Usage: test-common.sh CURR_MON_NAME MON_NAME'
|
||||||
|
echo
|
||||||
|
echo 'Monitor names are required. Names are given by "mons".
|
||||||
|
CURR_MON_NAME is your current monitor and the second one is reserved
|
||||||
|
for primary test.'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
Test_Common () {
|
||||||
|
echo 'TEST: Common Modes'
|
||||||
|
echo '#=========================#'
|
||||||
|
./mons
|
||||||
|
echo '#=========================#'
|
||||||
|
|
||||||
|
./mons -o ; echo "test: primary" ; sleep 8
|
||||||
|
./mons -s ; echo "test: second" ; sleep 8
|
||||||
|
./mons -e left ; echo "test: extend left" ; sleep 8
|
||||||
|
./mons -d ; echo "test: duplicate" ; sleep 8
|
||||||
|
./mons -m ; echo "test: mirror" ; sleep 8
|
||||||
|
./mons -e right ; echo "test: extend right" ; sleep 8
|
||||||
|
./mons -e top ; echo "test: extend top" ; sleep 8
|
||||||
|
./mons -e bottom ; echo "test: extend bottom" ; sleep 8
|
||||||
|
./mons -o ; echo "test: primary" ; sleep 8
|
||||||
|
./mons -s ; echo "test: second" ; sleep 8
|
||||||
|
./mons -o ; echo "test: primary"
|
||||||
|
}
|
||||||
|
|
||||||
|
./mons -o --primary "$1"
|
||||||
|
Test_Common
|
||||||
|
./mons -o --primary "$2"
|
||||||
|
echo "[ Primary has been set: $1 ]"
|
||||||
|
Test_Common
|
||||||
|
./mons -o --primary "$1"
|
24
test/test-select.sh
Normal file
24
test/test-select.sh
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
if [ "$#" -ne 3 ]; then
|
||||||
|
echo 'Usage: test-select.sh MON_ID1 MON_ID2 MON_ID3'
|
||||||
|
echo
|
||||||
|
echo 'Three monitor ids are required. Ids are given by `mons`.'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 'TEST: Selections'
|
||||||
|
echo '#=========================#'
|
||||||
|
./mons
|
||||||
|
echo '#=========================#'
|
||||||
|
|
||||||
|
./mons -O "$1" ; echo "test: single select $1" ; sleep 8
|
||||||
|
./mons -O "$2" ; echo "test: single select $2" ; sleep 8
|
||||||
|
./mons -O "$3" ; echo "test: single select $3" ; sleep 8
|
||||||
|
./mons -O "$1" ; echo "test: single select $1" ; sleep 8
|
||||||
|
./mons -S "$1,$2:R" ; echo "test: single select $1,$2:R" ; sleep 8
|
||||||
|
./mons -S "$1,$2:T" ; echo "test: multi select $1,$2:T" ; sleep 8
|
||||||
|
./mons -S "$3,$2:T" ; echo "test: multi select $3,$2:T" ; sleep 8
|
||||||
|
./mons -S "$2,$3:R" ; echo "test: multi select $2,$3:R" ; sleep 8
|
||||||
|
./mons -S "$3,$1:T" ; echo "test: multi select $3,$1:T" ; sleep 8
|
||||||
|
./mons -O "$1" ; echo "test: single select $1"
|
Loading…
Reference in New Issue
Block a user