"Fossies" - the Fresh Open Source Software Archive

Member "polysh-polysh-0.13/polysh/completion.py" (11 May 2020, 4281 Bytes) of package /linux/privat/polysh-polysh-0.13.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "completion.py" see the Fossies "Dox" file reference documentation.

    1 """Polysh - Tab Completion
    2 
    3 Copyright (c) 2006 Guillaume Chazarain <guichaz@gmail.com>
    4 Copyright (c) 2018 InnoGames GmbH
    5 """
    6 # This program is free software: you can redistribute it and/or modify
    7 # it under the terms of the GNU General Public License as published by
    8 # the Free Software Foundation, either version 2 of the License, or
    9 # (at your option) any later version.
   10 #
   11 # This program is distributed in the hope that it will be useful,
   12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
   13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14 # GNU General Public License for more details.
   15 #
   16 # You should have received a copy of the GNU General Public License
   17 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
   18 
   19 import glob
   20 import os
   21 import readline
   22 from typing import Optional, List, Set
   23 
   24 from polysh.control_commands_helpers import complete_control_command
   25 from polysh.control_commands_helpers import expand_local_path
   26 
   27 
   28 def complete_local_path(path: str) -> List[str]:
   29     def get_suffix(p: str) -> str:
   30         if os.path.isdir(p):
   31             return '/'
   32         return ''
   33     path = expand_local_path(path)
   34     paths = [p + get_suffix(p) for p in glob.glob(path + '*')]
   35     return paths
   36 
   37 
   38 def remove_dupes(words: List[str]) -> List[str]:
   39     added = set()  # type: Set[str]
   40     results = list()
   41     for w in words:
   42         stripped = w.rstrip('/ ')
   43         if stripped not in added:
   44             added.add(stripped)
   45             results.append(w)
   46     return results
   47 
   48 
   49 def read_commands_in_path() -> List[str]:
   50     commands = set()  # type: Set[str]
   51 
   52     for path in (os.getenv('PATH') or '').split(':'):
   53         if path:
   54             try:
   55                 listing = os.listdir(path)
   56             except OSError:
   57                 pass
   58             else:
   59                 commands |= set(listing)
   60     return list(commands)
   61 
   62 
   63 # All the words that have been typed in polysh. Used by the completion
   64 # mechanism.
   65 history_words = set()  # type: Set[str]
   66 
   67 # When listing possible completions, the complete() function is called with
   68 # an increasing state parameter until it returns None. Cache the completion
   69 # list instead of regenerating it for each completion item.
   70 completion_results = None
   71 
   72 # Commands in $PATH, used for the completion of the first word
   73 user_commands_in_path = read_commands_in_path()
   74 
   75 
   76 def complete(text: str, state: int) -> Optional[str]:
   77     """On tab press, return the next possible completion"""
   78     global completion_results
   79     if state == 0:
   80         line = readline.get_line_buffer()
   81         if line.startswith(':'):
   82             # Control command completion
   83             completion_results = complete_control_command(line, text)
   84         else:
   85             if line.startswith('!') and text and line.startswith(text):
   86                 dropped_exclam = True
   87                 text = text[1:]
   88             else:
   89                 dropped_exclam = False
   90             completion_results = []
   91             # Complete local paths
   92             completion_results += complete_local_path(text)
   93             # Complete from history
   94             l = len(text)
   95             completion_results += [w + ' ' for w in history_words if
   96                                    len(w) > l and w.startswith(text)]
   97             if readline.get_begidx() == 0:
   98                 # Completing first word from $PATH
   99                 completion_results += [w + ' ' for w in user_commands_in_path
  100                                            if len(w) > l and w.startswith(text)]
  101             completion_results = remove_dupes(completion_results)
  102             if dropped_exclam:
  103                 completion_results = ['!' + r for r in completion_results]
  104 
  105     if state < len(completion_results):
  106         return completion_results[state]
  107     completion_results = None
  108     return None
  109 
  110 
  111 def add_to_history(cmd: str) -> None:
  112     if len(history_words) < 10000:
  113         history_words.update(w for w in cmd.split() if len(w) > 1)
  114 
  115 
  116 def remove_last_history_item() -> None:
  117     """The user just typed a password..."""
  118     last = readline.get_current_history_length() - 1
  119     readline.remove_history_item(last)
  120 
  121 
  122 def install_completion_handler() -> None:
  123     readline.set_completer(complete)
  124     readline.parse_and_bind('tab: complete')
  125     readline.set_completer_delims(' \t\n')