Closed ninrod closed 2 years ago
Hi Folks. I'd really like to work on this even if I'm a lisp total begginer.
I'm trying to pinpoint the snippet I'd have to work on to write the fix, so here are my thoughts:
My first reaction was to look for the definition of the iw
text-object which I've found here.
Immediately I'm greeted with the symbol evil-word
. So I M-x ag
it and find nothing.
C-h v
and C-h f
does not seem to help either.
As the definition of evil-word
symbol is nowhere to be found on the code, which is weird, I'm really confused because the definition for evil-select-inner-object says that the first parameter, thing
, which is evil-word
, would be the anything understood by thing-at-point
, which, C-h f
tells me are:
Possibilities include `symbol', `list', `sexp', `defun',
`filename', `url', `email', `word', `sentence', `whitespace',
`line', `number', and `page'.
but there's no evil-word
. How does evil even knows that there's an evil-word
somewhere?
@edkolev @wasamasa @justbur, can you guys give me some pointers?
thanks in advance
The next step from here is finding out how new types for thingatpt
are registered:
;; This file provides routines for getting the "thing" at the location of
;; point, whatever that "thing" happens to be. The "thing" is defined by
;; its beginning and end positions in the buffer.
;;
;; The function bounds-of-thing-at-point finds the beginning and end
;; positions by moving first forward to the end of the "thing", and then
;; backwards to the beginning. By default, it uses the corresponding
;; forward-"thing" operator (eg. forward-word, forward-line).
@edkolev @wasamasa @justbur, can you guys give me some pointers?
Sure, here's a couple of tips:
C-h f
(and friends)w
) and selecting inner words (viw
, diw
, etc) because moving should move over new lines, but selecting must notA couple of more tips
M-x debug-on-entry
and see if the debugger pops up.M-x cancel-debug-on-entry
to remove the function. (forward-thing 'evil-word)
, which is a simple function that looks for a function called forward-THING
or forward-evil-word
in this case. You can see that this function is defined in evil-common.el.evil-forward-nearest
does and so on down the rabbit hole. There is a lot of evil-specific machinery in the evil repository, and unfortunately it takes some work to figure out how it all works together. The comments are helpful, but you have to read some code too.
thanks guys!
Ok, so I discovered that if I suppress the \n
here, then it works as intended, except, as @edkolev has already mentioned, w
does not jump over lines anymore. So my next thought is to duplicate the forward-evil-word definition and call it forward-evil-inner-word
. It's the exact same function, but without the \n
.
So I do that, and in here I change the inner-word text object definition to use my new forward function. All seems good. I restart emacs.
And it seems that I've done nothing. In fact, I even instrument the two forward functions, forward-evil-world
and foward-evil-inner-word
, and when I press diw
only the foward-evil-world
function gets debugged, which is all sorts of weird.
Is there some sort of cache thing going on? I find it very strange because if I go to the forward-evil-word
function and pull out the \n
, then it works.
Seems that some kind of cache is going on. Is that even possible?
here's how I bootstrap evil:
(use-package evil
:load-path "lisp/emacs-evil/evil"
:init
(use-package goto-chg
:ensure t)
(use-package undo-tree
:ensure t)
:config
(setcdr evil-insert-state-map nil) ;; emacsify insert state: http://stackoverflow.com/a/26573722/4921402
(define-key evil-insert-state-map [escape] 'evil-normal-state);; but [escape] should switch back to normal state, obviously.
(fset 'evil-visual-update-x-selection 'ignore);; Amazing hack lifted from: http://emacs.stackexchange.com/a/15054/12585
(evil-mode)
(evil-define-text-object ninrod/textobj-entire (count &optional beg end type)
(evil-range (point-min) (point-max)))
(define-key evil-outer-text-objects-map "e" 'ninrod/textobj-entire));; simulation of kana's textobj-entire
ps: lisp/emacs-evil/evil
is just this repo git cloned.
thanks in advance for any help.
So my next thought is to duplicate the forward-evil-word definition and call it forward-evil-inner-word. It's the exact same function, but without the \n.
Seems reasonable to me.
Seems that some kind of cache is going on. Is that even possible?
Check if you have .elc files in the "lisp/emacs-evil/evil" directory. Emacs will prefer loading that.
@justbur, there was no .elc file in that dir, but I just searched my ~/.emacs.d
, and sure enough:
emacs.d ❯ w
~/.emacs.d at ninrod@ninbook using -zsh ❯
.emacs.d ❯ find . -name '*.elc' | ag evil | wc -l
60
.emacs.d ❯
among those 60 results:
./elpa/evil-20170512.1253/evil-command-window.elc
./elpa/evil-20170512.1253/evil-commands.elc
./elpa/evil-20170512.1253/evil-common.elc
./elpa/evil-20170512.1253/evil-core.elc
./elpa/evil-20170512.1253/evil-digraphs.elc
./elpa/evil-20170512.1253/evil-ex.elc
./elpa/evil-20170512.1253/evil-integration.elc
./elpa/evil-20170512.1253/evil-jumps.elc
./elpa/evil-20170512.1253/evil-macros.elc
./elpa/evil-20170512.1253/evil-maps.elc
./elpa/evil-20170512.1253/evil-repeat.elc
./elpa/evil-20170512.1253/evil-search.elc
./elpa/evil-20170512.1253/evil-states.elc
./elpa/evil-20170512.1253/evil-types.elc
./elpa/evil-20170512.1253/evil-vars.elc
./elpa/evil-20170512.1253/evil.elc
but that is not the cause. I went ahead and deleted the elc files and restarted emacs. issue continues.
Also, I verified that if I create a new inner object with a different name, say, evil-inner-spaces
, and bind that to, say, s
, and press dis
, then it works.
seems that diw
is selecting forward-evil-word despite of what might be implemented in the evil-inner-word definition function.
From some cursory testing in Vim and Emacs, the issue appears to be that in Vim, the movement to figure out the bounds of that text object seem to be constrained to the current line. In Emacs they aren't. To prove this, extend the example by adding more whitespace lines between foo and bar.
I'd personally never caught that one because I'd delete whitespace with 0dw
.
@ninrod you can run counsel-find-symbol
to go to the definition of the symbol under point. If you don't use counsel
, there's probably another way to do this, with xref-find-definitions
maybe.
This approach should be able to take you to the function emacs is using, rather than the function you think emacs is using.
I'd personally never caught that one because I'd delete whitespace with 0dw.
@wasamasa yes! I have just discovered this combination while trying to fix this. At this point, I'm just trying to fix this for the evil learning value.
@ninrod you can run counsel-find-symbol to go to the definition of the symbol under point.
@edkolev ok. but what symbol should be under point, in my case? I don't think I follow.
Sorry, I wasn't clear enough - with your cursor on forward-evil-inner-word
, counsel-find-symbol
should take you to its definition - you'll be able to see if it's defined where you expect it to be (the evil git repo where you made your changes, or the .emacs.d/elpa/evil-123 dir, or someplace else).
@edkolev, right. But the forward-evil-inner-word
symbol is a function that I wrote in the git cloned repo. You are actually reffering to forward-evil-word
, right?
So you are saying that I could write forward-evil-word
in the scratch buffer and counsel-find-symbol it, is that correct?
Correct :)
Issue type
Environment
Emacs version: GNU Emacs 25.2.1 (x86_64-apple-darwin16.4.0, NS appkit-1504.81 Version 10.12.3 (Build 16D32)) of 2017-03-11
Operating System: macOS Sierra.
Evil version: 1.2.12 Evil installation type: MELPA through use package. Graphical/Terminal: Graphical Terminal multiplexer: does not apply.
Reproduction steps
bar
word.bar
word typediw
.Expected behavior
the buffer should now display:
Actual behavior
the buffer instead displays:
Further notes
vim behaves as expected. emacs eats the above line's line ending.