(root)/
texinfo-7.1/
info/
m-x.c
       1  /* m-x.c -- Meta-x minibuffer reader.
       2  
       3     Copyright 1993-2023 Free Software Foundation, Inc.
       4  
       5     This program is free software: you can redistribute it and/or modify
       6     it under the terms of the GNU General Public License as published by
       7     the Free Software Foundation, either version 3 of the License, or
       8     (at your option) any later version.
       9  
      10     This program is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13     GNU General Public License for more details.
      14  
      15     You should have received a copy of the GNU General Public License
      16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      17  
      18     Originally written by Brian Fox. */
      19  
      20  #include "info.h"
      21  #include "display.h"
      22  #include "session.h"
      23  #include "echo-area.h"
      24  #include "funs.h"
      25  
      26  /* **************************************************************** */
      27  /*                                                                  */
      28  /*                     Reading Named Commands                       */
      29  /*                                                                  */
      30  /* **************************************************************** */
      31  
      32  /* Read the name of an Info function in the echo area and return the
      33     name.  A return value of NULL indicates that no function name could
      34     be read. */
      35  char *
      36  read_function_name (char *prompt, WINDOW *window)
      37  {
      38    register int i;
      39    char *line;
      40    REFERENCE **array = NULL;
      41    size_t array_index = 0, array_slots = 0;
      42  
      43    /* Make an array of REFERENCE which actually contains the names of
      44       the functions available in Info. */
      45    for (i = 0; function_doc_array[i].func; i++)
      46      {
      47        REFERENCE *entry;
      48  
      49        entry = xmalloc (sizeof (REFERENCE));
      50        entry->label = xstrdup (function_doc_array[i].func_name);
      51        entry->nodename = NULL;
      52        entry->filename = NULL;
      53  
      54        add_pointer_to_array (entry, array_index, array, array_slots, 200);
      55      }
      56  
      57    line = info_read_completing_in_echo_area (prompt, array);
      58    info_free_references (array);
      59  
      60    return line;
      61  }
      62  
      63  DECLARE_INFO_COMMAND (describe_command,
      64     _("Read the name of an Info command and describe it"))
      65  {
      66    char *line;
      67  
      68    line = read_function_name (_("Describe command: "), window);
      69  
      70    if (!line)
      71      {
      72        info_abort_key (active_window, count);
      73        return;
      74      }
      75  
      76    if (*line)
      77      {
      78        InfoCommand *cmd = named_function (line);
      79        if (cmd)
      80          {
      81            window_message_in_echo_area ("%s: %s.",
      82                                         line, function_documentation (cmd));
      83          }
      84      }
      85    free (line);
      86  }
      87  
      88  DECLARE_INFO_COMMAND (info_execute_command,
      89     _("Read a command name in the echo area and execute it"))
      90  {
      91    char *line;
      92    char *keys;
      93    char *prompt;
      94  
      95    keys = where_is (info_keymap, InfoCmd(info_execute_command));
      96    /* If the where_is () function thinks that this command doesn't exist,
      97       there's something very wrong!  */
      98    if (!keys)
      99      abort();
     100  
     101    if (info_explicit_arg || count != 1)
     102      xasprintf (&prompt, "%d %s ", count, keys);
     103    else
     104      xasprintf (&prompt, "%s ", keys);
     105  
     106    /* Ask the completer to read a reference for us. */
     107    line = read_function_name (prompt, window);
     108    free (prompt);
     109  
     110    /* User aborted? */
     111    if (!line)
     112      {
     113        info_abort_key (active_window, count);
     114        return;
     115      }
     116  
     117    /* User accepted "default"?  (There is none.) */
     118    if (!*line)
     119      {
     120        free (line);
     121        return;
     122      }
     123  
     124    /* User wants to execute a named command.  Do it. */
     125    {
     126      InfoCommand *command;
     127  
     128      if ((active_window != the_echo_area) &&
     129          (strncmp (line, "echo-area-", 10) == 0))
     130        {
     131          free (line);
     132          info_error (_("Cannot execute an 'echo-area' command here"));
     133          return;
     134        }
     135  
     136      command = named_function (line);
     137      free (line);
     138  
     139      if (command && command->func)
     140        (*command->func) (active_window, count, 0);
     141    }
     142  }
     143  
     144  /* Okay, now that we have M-x, let the user set the screen height. */
     145  DECLARE_INFO_COMMAND (set_screen_height,
     146    _("Set the height of the displayed window"))
     147  {
     148    int new_height, old_height = screenheight;
     149  
     150    if (info_explicit_arg || count != 1)
     151      new_height = count;
     152    else
     153      {
     154        char prompt[80];
     155        char *line;
     156  
     157        new_height = screenheight;
     158  
     159        sprintf (prompt, _("Set screen height to (%d): "), new_height);
     160  
     161        line = info_read_in_echo_area (prompt);
     162  
     163        /* If the user aborted, do that now. */
     164        if (!line)
     165          {
     166            info_abort_key (active_window, count);
     167            return;
     168          }
     169  
     170        /* Find out what the new height is supposed to be. */
     171        if (*line)
     172          new_height = atoi (line);
     173  
     174        free (line);
     175      }
     176  
     177    terminal_clear_screen ();
     178    display_clear_display (the_display);
     179    screenheight = new_height;
     180  #ifdef SET_SCREEN_SIZE_HELPER
     181    SET_SCREEN_SIZE_HELPER;
     182  #endif
     183    if (screenheight == old_height)
     184      {
     185        /* Display dimensions didn't actually change, so
     186  	 window_new_screen_size won't do anything, but we've
     187  	 already cleared the display above.  Undo the damage.  */
     188        window_mark_chain (windows, W_UpdateWindow);
     189        display_update_display ();
     190      }
     191    else
     192      {
     193        display_initialize_display (screenwidth, screenheight);
     194        window_new_screen_size (screenwidth, screenheight);
     195      }
     196  }