From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Oleksandr Manzyuk Newsgroups: gmane.emacs.help Subject: Inner workings of `pcomplete' Date: Tue, 07 Feb 2012 23:31:03 +0000 Message-ID: <87pqdqz0eg.fsf@gmail.com> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: dough.gmane.org 1328658947 31403 80.91.229.3 (7 Feb 2012 23:55:47 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Tue, 7 Feb 2012 23:55:47 +0000 (UTC) To: help-gnu-emacs@gnu.org Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Wed Feb 08 00:55:47 2012 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([140.186.70.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Ruut1-0003ds-2H for geh-help-gnu-emacs@m.gmane.org; Wed, 08 Feb 2012 00:55:47 +0100 Original-Received: from localhost ([::1]:54851 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ruut0-0001tf-Db for geh-help-gnu-emacs@m.gmane.org; Tue, 07 Feb 2012 18:55:46 -0500 Original-Received: from eggs.gnu.org ([140.186.70.92]:43383) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RuuVD-0007ND-U6 for help-gnu-emacs@gnu.org; Tue, 07 Feb 2012 18:31:15 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RuuV9-0007hK-Lx for help-gnu-emacs@gnu.org; Tue, 07 Feb 2012 18:31:11 -0500 Original-Received: from mail-wi0-f169.google.com ([209.85.212.169]:47529) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RuuV9-0007gx-7n for help-gnu-emacs@gnu.org; Tue, 07 Feb 2012 18:31:07 -0500 Original-Received: by wibhj13 with SMTP id hj13so7425761wib.0 for ; Tue, 07 Feb 2012 15:31:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=from:to:subject:date:message-id:mime-version:content-type; bh=YwTXFgSSNkwQwtZ8iTWf+uoTxpGlr+2gfvai8OMjNOY=; b=eMlK1mtpT3o95BkQZ71H/acP+s3Q8PeCPYv/n5PGFL6rdLqZIZMw3JJZq3srclwXcd Qb7R+JqhwalMXiq6qfTlqsDCFWLPeVI2/lwPcwHygXzckK7dXB0/rHBvyhnqhQRM8eju 2xXoxVHKAngehYyMZ8m1RYpSak00LOPIbfWNg= Original-Received: by 10.180.101.200 with SMTP id fi8mr37002624wib.20.1328657465857; Tue, 07 Feb 2012 15:31:05 -0800 (PST) Original-Received: from paddy (089-101-118058.ntlworld.ie. [89.101.118.58]) by mx.google.com with ESMTPS id j16sm61206014wie.4.2012.02.07.15.31.04 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 07 Feb 2012 15:31:05 -0800 (PST) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.212.169 X-Mailman-Approved-At: Tue, 07 Feb 2012 18:55:42 -0500 X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.help:83672 Archived-At: Dear all, I'm working on a small package aiming at providing basic completion for GHCi commands in `inferior-haskell-mode': https://github.com/manzyuk/ghci-completion The package uses a combination of the standard completion UI (for GHCi commands) with `pcomplete' (for arguments to particular commands). I've been experimenting recently with identifier completion and I've stumbled upon the following issue. I'm not sure whether it is a bug in the code or in my understanding of it. Everything below refers to the latest Emacs 24 (24.0.93.1). To enable `pcomplete' in `inferior-haskell-mode', I add the function `pcomplete-completions-at-point' to `comint-dynamic-complete-functions'. Experimenting with identifier completion, I started to receive the errors "Wrong type argument: stringp, nil", which I traced back to the call (pcomplete--common-quoted-suffix pcomplete-stub buftext) in the body of `pcomplete-completions-at-point'. Now, `pcomplete-stub' is bound to nil at the beginning of the function using let* and it is expected that the function `pcomplete-completions', which is called later, will change the value of `pcomplete-stub' by side-effects. Apparently, this doesn't happen and `pcomplete--common-quoted-suffix' receives nil as its first argument, which triggers the error. `pcomplete-stub' is declared using defvar, and the top comment of the file contains -*- lexical-binding: t -*-, so `pcomplete-stub' should be a special variable. This is not the case: 1. emacs -Q 2. M-: (boundp 'pcomplete-stub) RET ==> nil 3. M-x shell 4. M-: (boundp 'pcomplete-stub) RET ==> t 5. M-: (special-variable-p 'pcomplete-stub) RET ==> nil 6. Open the file `pcomplete.el' (for example, by looking up the variable `pcomplete-stub') and M-x eval-buffer. Now (special-variable-p 'pcomplete-stub) evaluates to t. What is going on here? To confirm my guess that `pcomplete-stub' was not a special variable, I tried the following workaround: I removed `pcomplete-stub' from the let* bindings, so that no lexical binding was created for it, and hence its global value was used in the body of let*. The errors were gone and completion started to work as I wanted it to. Actually, to make identifier completion really work the way I wanted, I had to make another change in `pcomplete-completions-at-point', namely to replace (when completions ...) with (unless (functionp completions) ...) The thing is, `completions' (the value returned by the function `pcomplete-completions') can be a function. In fact, it is a function in the case of "cd" command in shell (try to type "cd " at the shell prompt and M-: (pcomplete-completions)). However, it is also passed as a table argument to the function `complete-with-action', whose documentation says that this argument should not be a function. What happens if it is a function? I don't know, but somehow, with the old code allowing `completions' to be a function, I get the behavior that `pcomplete-completions-at-point' always succeeds (returns a suitably formatted plist, even though its components don't always produce completions!), leaving no opportunity to the next function in `comint-dynamic-complete-functions' (identifier completion) to fire. I should mention that by this change I've lost some of completion functionality (e.g., "cd" in shell doesn't offer the list of directories), so this is clearly not the right way to do it. What is the right way then? I'm confused. Any comments and suggestions would be greatly appreciated. Regards, Sasha